зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1066280 - Remove SurfaceStream. - r=kamidphish,mattwoodrow
This commit is contained in:
Родитель
97fbd15434
Коммит
9b7291ca7a
|
@ -116,7 +116,6 @@
|
|||
// method in SkTypes.h
|
||||
#ifdef USE_SKIA
|
||||
#include "SkiaGLGlue.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SurfaceTypes.h"
|
||||
#endif
|
||||
|
||||
|
@ -711,7 +710,7 @@ public:
|
|||
CanvasRenderingContext2DUserData* self =
|
||||
static_cast<CanvasRenderingContext2DUserData*>(aData);
|
||||
CanvasRenderingContext2D* context = self->mContext;
|
||||
if (!context || !context->mStream || !context->mTarget)
|
||||
if (!context || !context->mTarget)
|
||||
return;
|
||||
|
||||
// Since SkiaGL default to store drawing command until flush
|
||||
|
@ -826,7 +825,6 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
|
|||
, mZero(false), mOpaque(false)
|
||||
, mResetLayer(true)
|
||||
, mIPC(false)
|
||||
, mStream(nullptr)
|
||||
, mIsEntireFrameInvalid(false)
|
||||
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
|
||||
, mInvalidateCount(0)
|
||||
|
@ -912,7 +910,6 @@ CanvasRenderingContext2D::Reset()
|
|||
}
|
||||
|
||||
mTarget = nullptr;
|
||||
mStream = nullptr;
|
||||
|
||||
// reset hit regions
|
||||
mHitRegionsOptions.ClearAndRetainStorage();
|
||||
|
@ -1025,8 +1022,10 @@ CanvasRenderingContext2D::Redraw(const mgfx::Rect &r)
|
|||
void
|
||||
CanvasRenderingContext2D::DidRefresh()
|
||||
{
|
||||
if (mStream && mStream->GLContext()) {
|
||||
mStream->GLContext()->FlushIfHeavyGLCallsSinceLastFlush();
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
if (glue) {
|
||||
auto gl = glue->GetGLContext();
|
||||
gl->FlushIfHeavyGLCallsSinceLastFlush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1052,7 +1051,6 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
|
|||
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
|
||||
RefPtr<DrawTarget> oldTarget = mTarget;
|
||||
mTarget = nullptr;
|
||||
mStream = nullptr;
|
||||
mResetLayer = true;
|
||||
|
||||
// Recreate target using the new rendering mode
|
||||
|
@ -1223,8 +1221,6 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode)
|
|||
if (glue && glue->GetGrContext() && glue->GetGLContext()) {
|
||||
mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
|
||||
if (mTarget) {
|
||||
mStream = gl::SurfaceStream::CreateForType(gl::SurfaceStreamType::TripleBuffer,
|
||||
glue->GetGLContext());
|
||||
AddDemotableContext(this);
|
||||
} else {
|
||||
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
|
||||
|
@ -4857,15 +4853,9 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
aOldLayer->GetUserData(&g2DContextLayerUserData));
|
||||
|
||||
CanvasLayer::Data data;
|
||||
if (mStream) {
|
||||
#ifdef USE_SKIA
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
|
||||
if (glue) {
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mStream = mStream.get();
|
||||
}
|
||||
#endif
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
if (glue) {
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
}
|
||||
|
@ -4902,25 +4892,20 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
|
||||
|
||||
CanvasLayer::Data data;
|
||||
if (mStream) {
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
data.mSize = nsIntSize(mWidth, mHeight);
|
||||
data.mHasAlpha = !mOpaque;
|
||||
|
||||
if (glue) {
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
#if USE_SKIA
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
#endif
|
||||
data.mStream = mStream.get();
|
||||
data.mTexID = (uint32_t)((uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE));
|
||||
}
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
GLuint skiaGLTex = (GLuint)(uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE);
|
||||
if (glue && skiaGLTex) {
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mFrontbufferGLTex = skiaGLTex;
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
}
|
||||
|
||||
data.mSize = nsIntSize(mWidth, mHeight);
|
||||
data.mHasAlpha = !mOpaque;
|
||||
|
||||
canvasLayer->Initialize(data);
|
||||
uint32_t flags = mOpaque ? Layer::CONTENT_OPAQUE : 0;
|
||||
canvasLayer->SetContentFlags(flags);
|
||||
|
|
|
@ -34,7 +34,6 @@ class nsXULElement;
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SourceSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
@ -765,8 +764,6 @@ protected:
|
|||
// sErrorTarget.
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
|
||||
|
||||
RefPtr<gl::SurfaceStream> mStream;
|
||||
|
||||
/**
|
||||
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
|
||||
* Redraw is called, reset to false when Render is called.
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "prlink.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "GfxTexturesReporter.h"
|
||||
#include "TextureGarbageBin.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "GLBlitHelper.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceStream.h"
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "SharedSurfaceGralloc.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
#ifndef SCREEN_BUFFER_H_
|
||||
#define SCREEN_BUFFER_H_
|
||||
|
||||
#include "SurfaceTypes.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -30,7 +30,6 @@ class GLContext;
|
|||
class SharedSurface;
|
||||
class ShSurfHandle;
|
||||
class SurfaceFactory;
|
||||
class SurfaceStream;
|
||||
|
||||
class DrawBuffer
|
||||
{
|
||||
|
@ -89,7 +88,7 @@ protected:
|
|||
const GLuint mDepthRB;
|
||||
const GLuint mStencilRB;
|
||||
// note no mColorRB here: this is provided by mSurf.
|
||||
SharedSurface* mSurf; // Owned by GLScreenBuffer's SurfaceStream.
|
||||
SharedSurface* mSurf;
|
||||
|
||||
ReadBuffer(GLContext* gl,
|
||||
GLuint fb,
|
||||
|
|
|
@ -234,7 +234,7 @@ public:
|
|||
}
|
||||
|
||||
SharedSurface* Surf() const {
|
||||
MOZ_ASSERT(mSurf);
|
||||
MOZ_ASSERT(mSurf.get());
|
||||
return mSurf.get();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,559 +0,0 @@
|
|||
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SurfaceStream.h"
|
||||
|
||||
#include "gfxPoint.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
SurfaceStreamType
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc,
|
||||
bool preserveBuffer)
|
||||
{
|
||||
if (omtc == SurfaceStream::OffMainThread) {
|
||||
if (preserveBuffer)
|
||||
return SurfaceStreamType::TripleBuffer_Copy;
|
||||
else
|
||||
return SurfaceStreamType::TripleBuffer_Async;
|
||||
} else {
|
||||
if (preserveBuffer)
|
||||
return SurfaceStreamType::SingleBuffer;
|
||||
else
|
||||
return SurfaceStreamType::TripleBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
TemporaryRef<SurfaceStream>
|
||||
SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glContext, SurfaceStream* prevStream)
|
||||
{
|
||||
RefPtr<SurfaceStream> result;
|
||||
|
||||
switch (type) {
|
||||
case SurfaceStreamType::SingleBuffer:
|
||||
result = new SurfaceStream_SingleBuffer(prevStream);
|
||||
break;
|
||||
case SurfaceStreamType::TripleBuffer_Copy:
|
||||
result = new SurfaceStream_TripleBuffer_Copy(prevStream);
|
||||
break;
|
||||
case SurfaceStreamType::TripleBuffer_Async:
|
||||
result = new SurfaceStream_TripleBuffer_Async(prevStream);
|
||||
break;
|
||||
case SurfaceStreamType::TripleBuffer:
|
||||
result = new SurfaceStream_TripleBuffer(prevStream);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid Type.");
|
||||
}
|
||||
|
||||
result->mGLContext = glContext;
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory)
|
||||
{
|
||||
if (!mProducer) {
|
||||
New(factory, src->mSize, &mProducer);
|
||||
if (!mProducer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(src->mSize == mProducer->mSize, "Size mismatch");
|
||||
|
||||
SharedSurface::ProdCopy(src, mProducer.get(), factory);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size,
|
||||
UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
MOZ_ASSERT(!surf);
|
||||
surf = factory->NewSharedSurface(size);
|
||||
|
||||
if (surf) {
|
||||
// Before next use, wait until SharedSurface's buffer
|
||||
// is no longer being used.
|
||||
surf->WaitForBufferOwnership();
|
||||
#ifdef DEBUG
|
||||
mSurfaces.insert(surf.get());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::MoveTo(UniquePtr<SharedSurface>* slotFrom,
|
||||
UniquePtr<SharedSurface>* slotTo)
|
||||
{
|
||||
MOZ_ASSERT(slotFrom);
|
||||
UniquePtr<SharedSurface>& from = *slotFrom;
|
||||
|
||||
MOZ_ASSERT(slotTo);
|
||||
UniquePtr<SharedSurface>& to = *slotTo;
|
||||
|
||||
MOZ_ASSERT(!to);
|
||||
to = Move(from);
|
||||
MOZ_ASSERT(!from);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::Recycle(SurfaceFactory* factory, UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
if (surf) {
|
||||
#ifdef DEBUG
|
||||
mSurfaces.erase(surf.get());
|
||||
#endif
|
||||
factory->Recycle(Move(surf));
|
||||
}
|
||||
MOZ_ASSERT(!surf);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::Delete(UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
if (surf) {
|
||||
#ifdef DEBUG
|
||||
mSurfaces.erase(surf.get());
|
||||
#endif
|
||||
surf = nullptr;
|
||||
}
|
||||
MOZ_ASSERT(!surf);
|
||||
}
|
||||
|
||||
UniquePtr<SharedSurface>
|
||||
SurfaceStream::Surrender(UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (surf) {
|
||||
mSurfaces.erase(surf.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
UniquePtr<SharedSurface> ret = Move(surf);
|
||||
MOZ_ASSERT(!surf);
|
||||
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
// Move `surfSlot` to `return`, but record that the surf is now part of
|
||||
// this stream.
|
||||
UniquePtr<SharedSurface>
|
||||
SurfaceStream::Absorb(UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (surf) {
|
||||
mSurfaces.insert(surf.get());
|
||||
}
|
||||
#endif
|
||||
|
||||
UniquePtr<SharedSurface> ret = Move(surf);
|
||||
MOZ_ASSERT(!surf);
|
||||
|
||||
return Move(ret);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::Scrap(UniquePtr<SharedSurface>* surfSlot)
|
||||
{
|
||||
MOZ_ASSERT(surfSlot);
|
||||
UniquePtr<SharedSurface>& surf = *surfSlot;
|
||||
|
||||
if (surf) {
|
||||
mScraps.Push(Move(surf));
|
||||
}
|
||||
MOZ_ASSERT(!surf);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::RecycleScraps(SurfaceFactory* factory)
|
||||
{
|
||||
while (!mScraps.Empty()) {
|
||||
UniquePtr<SharedSurface> cur = mScraps.Pop();
|
||||
|
||||
Recycle(factory, &cur);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceStream
|
||||
|
||||
SurfaceStream::SurfaceStream(SurfaceStreamType type,
|
||||
SurfaceStream* prevStream)
|
||||
: mType(type)
|
||||
, mProducer(nullptr)
|
||||
, mMonitor("SurfaceStream monitor")
|
||||
, mIsAlive(true)
|
||||
{
|
||||
MOZ_ASSERT(!prevStream || mType != prevStream->mType,
|
||||
"We should not need to create a SurfaceStream from another "
|
||||
"of the same type.");
|
||||
}
|
||||
|
||||
SurfaceStream::~SurfaceStream()
|
||||
{
|
||||
Delete(&mProducer);
|
||||
|
||||
while (!mScraps.Empty()) {
|
||||
UniquePtr<SharedSurface> cur = mScraps.Pop();
|
||||
|
||||
Delete(&cur);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mSurfaces.empty());
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream::SwapConsumer()
|
||||
{
|
||||
MOZ_ASSERT(mIsAlive);
|
||||
|
||||
SharedSurface* ret = SwapConsumer_NoWait();
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
|
||||
if (!ret->WaitSync()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream::Resize(SurfaceFactory* factory, const gfx::IntSize& size)
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mProducer) {
|
||||
Scrap(&mProducer);
|
||||
}
|
||||
|
||||
New(factory, size, &mProducer);
|
||||
return mProducer.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceStream_SingleBuffer
|
||||
|
||||
SurfaceStream_SingleBuffer::SurfaceStream_SingleBuffer(SurfaceStream* prevStream)
|
||||
: SurfaceStream(SurfaceStreamType::SingleBuffer, prevStream)
|
||||
, mConsumer(nullptr)
|
||||
{
|
||||
if (!prevStream)
|
||||
return;
|
||||
|
||||
UniquePtr<SharedSurface> prevProducer;
|
||||
UniquePtr<SharedSurface> prevConsumer;
|
||||
prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
|
||||
|
||||
mProducer = Absorb(&prevProducer);
|
||||
mConsumer = Absorb(&prevConsumer);
|
||||
}
|
||||
|
||||
SurfaceStream_SingleBuffer::~SurfaceStream_SingleBuffer()
|
||||
{
|
||||
Delete(&mConsumer);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream_SingleBuffer::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer)
|
||||
{
|
||||
MOZ_ASSERT(out_producer);
|
||||
MOZ_ASSERT(out_consumer);
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
*out_producer = Surrender(&mProducer);
|
||||
*out_consumer = Surrender(&mConsumer);
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_SingleBuffer::SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size)
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mConsumer) {
|
||||
Recycle(factory, &mConsumer);
|
||||
}
|
||||
|
||||
if (mProducer) {
|
||||
// Fence now, before we start (maybe) juggling Prod around.
|
||||
mProducer->Fence();
|
||||
|
||||
// Size mismatch means we need to squirrel the current Prod
|
||||
// into Cons, and leave Prod empty, so it gets a new surface below.
|
||||
bool needsNewBuffer = mProducer->mSize != size;
|
||||
|
||||
// Even if we're the right size, if the type has changed, and we don't
|
||||
// need to preserve, we should switch out for (presumedly) better perf.
|
||||
if (mProducer->mType != factory->mType &&
|
||||
!factory->mCaps.preserve)
|
||||
{
|
||||
needsNewBuffer = true;
|
||||
}
|
||||
|
||||
if (needsNewBuffer) {
|
||||
MoveTo(&mProducer, &mConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
// The old Prod (if there every was one) was invalid,
|
||||
// so we need a new one.
|
||||
if (!mProducer) {
|
||||
New(factory, size, &mProducer);
|
||||
}
|
||||
|
||||
return mProducer.get();
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_SingleBuffer::SwapConsumer_NoWait()
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
// Use Cons, if present.
|
||||
// Otherwise, just use Prod directly.
|
||||
SharedSurface* toConsume = mConsumer.get();
|
||||
if (!toConsume)
|
||||
toConsume = mProducer.get();
|
||||
|
||||
return toConsume;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceStream_TripleBuffer_Copy
|
||||
|
||||
SurfaceStream_TripleBuffer_Copy::SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream)
|
||||
: SurfaceStream(SurfaceStreamType::TripleBuffer_Copy, prevStream)
|
||||
, mStaging(nullptr)
|
||||
, mConsumer(nullptr)
|
||||
{
|
||||
if (!prevStream)
|
||||
return;
|
||||
|
||||
UniquePtr<SharedSurface> prevProducer;
|
||||
UniquePtr<SharedSurface> prevConsumer;
|
||||
prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
|
||||
|
||||
mProducer = Absorb(&prevProducer);
|
||||
mConsumer = Absorb(&prevConsumer);
|
||||
}
|
||||
|
||||
SurfaceStream_TripleBuffer_Copy::~SurfaceStream_TripleBuffer_Copy()
|
||||
{
|
||||
Delete(&mStaging);
|
||||
Delete(&mConsumer);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream_TripleBuffer_Copy::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer)
|
||||
{
|
||||
MOZ_ASSERT(out_producer);
|
||||
MOZ_ASSERT(out_consumer);
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
*out_producer = Surrender(&mProducer);
|
||||
*out_consumer = Surrender(&mConsumer);
|
||||
|
||||
if (!*out_consumer)
|
||||
*out_consumer = Surrender(&mStaging);
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_TripleBuffer_Copy::SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size)
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
RecycleScraps(factory);
|
||||
if (mProducer) {
|
||||
if (mStaging) {
|
||||
// We'll re-use this for a new mProducer later on if
|
||||
// the size remains the same
|
||||
Recycle(factory, &mStaging);
|
||||
}
|
||||
|
||||
MoveTo(&mProducer, &mStaging);
|
||||
mStaging->Fence();
|
||||
|
||||
New(factory, size, &mProducer);
|
||||
|
||||
if (mProducer &&
|
||||
mStaging->mSize == mProducer->mSize)
|
||||
{
|
||||
SharedSurface::ProdCopy(mStaging.get(), mProducer.get(), factory);
|
||||
}
|
||||
} else {
|
||||
New(factory, size, &mProducer);
|
||||
}
|
||||
|
||||
return mProducer.get();
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_TripleBuffer_Copy::SwapConsumer_NoWait()
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
|
||||
if (mStaging) {
|
||||
Scrap(&mConsumer);
|
||||
MoveTo(&mStaging, &mConsumer);
|
||||
}
|
||||
|
||||
return mConsumer.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceStream_TripleBuffer
|
||||
|
||||
void SurfaceStream_TripleBuffer::Init(SurfaceStream* prevStream)
|
||||
{
|
||||
if (!prevStream)
|
||||
return;
|
||||
|
||||
UniquePtr<SharedSurface> prevProducer;
|
||||
UniquePtr<SharedSurface> prevConsumer;
|
||||
prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
|
||||
|
||||
mProducer = Absorb(&prevProducer);
|
||||
mConsumer = Absorb(&prevConsumer);
|
||||
}
|
||||
|
||||
SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStreamType type,
|
||||
SurfaceStream* prevStream)
|
||||
: SurfaceStream(type, prevStream)
|
||||
, mStaging(nullptr)
|
||||
, mConsumer(nullptr)
|
||||
{
|
||||
SurfaceStream_TripleBuffer::Init(prevStream);
|
||||
}
|
||||
|
||||
SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStream* prevStream)
|
||||
: SurfaceStream(SurfaceStreamType::TripleBuffer, prevStream)
|
||||
, mStaging(nullptr)
|
||||
, mConsumer(nullptr)
|
||||
{
|
||||
SurfaceStream_TripleBuffer::Init(prevStream);
|
||||
}
|
||||
|
||||
SurfaceStream_TripleBuffer::~SurfaceStream_TripleBuffer()
|
||||
{
|
||||
Delete(&mStaging);
|
||||
Delete(&mConsumer);
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream_TripleBuffer::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer)
|
||||
{
|
||||
MOZ_ASSERT(out_producer);
|
||||
MOZ_ASSERT(out_consumer);
|
||||
|
||||
mIsAlive = false;
|
||||
|
||||
*out_producer = Surrender(&mProducer);
|
||||
*out_consumer = Surrender(&mConsumer);
|
||||
|
||||
if (!*out_consumer)
|
||||
*out_consumer = Surrender(&mStaging);
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size)
|
||||
{
|
||||
PROFILER_LABEL("SurfaceStream_TripleBuffer", "SwapProducer",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mProducer) {
|
||||
RecycleScraps(factory);
|
||||
|
||||
// If WaitForCompositor succeeds, mStaging has moved to mConsumer.
|
||||
// If it failed, we might have to scrap it.
|
||||
if (mStaging) {
|
||||
WaitForCompositor();
|
||||
}
|
||||
if (mStaging) {
|
||||
Scrap(&mStaging);
|
||||
}
|
||||
|
||||
MoveTo(&mProducer, &mStaging);
|
||||
mStaging->Fence();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mProducer);
|
||||
New(factory, size, &mProducer);
|
||||
|
||||
return mProducer.get();
|
||||
}
|
||||
|
||||
SharedSurface*
|
||||
SurfaceStream_TripleBuffer::SwapConsumer_NoWait()
|
||||
{
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mStaging) {
|
||||
Scrap(&mConsumer);
|
||||
MoveTo(&mStaging, &mConsumer);
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
|
||||
return mConsumer.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceStream_TripleBuffer_Async
|
||||
|
||||
SurfaceStream_TripleBuffer_Async::SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream)
|
||||
: SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async,
|
||||
prevStream)
|
||||
{
|
||||
}
|
||||
|
||||
SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream_TripleBuffer_Async::WaitForCompositor()
|
||||
{
|
||||
PROFILER_LABEL("SurfaceStream_TripleBuffer_Async",
|
||||
"WaitForCompositor",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
// If we haven't be notified within 100ms, then
|
||||
// something must have happened and it will never arrive.
|
||||
// Bail out to avoid deadlocking.
|
||||
mMonitor.Wait(PR_MillisecondsToInterval(100));
|
||||
}
|
||||
|
||||
} /* namespace gfx */
|
||||
} /* namespace mozilla */
|
|
@ -1,227 +0,0 @@
|
|||
/* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef SURFACESTREAM_H_
|
||||
#define SURFACESTREAM_H_
|
||||
|
||||
#include <stack>
|
||||
#include <set>
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/GenericRefCounted.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "SurfaceTypes.h"
|
||||
#include "SharedSurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
class SurfaceFactory;
|
||||
|
||||
// Owned by: ScreenBuffer
|
||||
class SurfaceStream : public GenericAtomicRefCounted
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream)
|
||||
typedef enum {
|
||||
MainThread,
|
||||
OffMainThread
|
||||
} OMTC;
|
||||
|
||||
static SurfaceStreamType ChooseGLStreamType(OMTC omtc,
|
||||
bool preserveBuffer);
|
||||
|
||||
static TemporaryRef<SurfaceStream> CreateForType(SurfaceStreamType type,
|
||||
mozilla::gl::GLContext* glContext,
|
||||
SurfaceStream* prevStream = nullptr);
|
||||
|
||||
const SurfaceStreamType mType;
|
||||
|
||||
mozilla::gl::GLContext* GLContext() const { return mGLContext; }
|
||||
|
||||
|
||||
protected:
|
||||
// |mProd| is owned by us, but can be ripped away when
|
||||
// creating a new GLStream from this one.
|
||||
UniquePtr<SharedSurface> mProducer;
|
||||
#ifdef DEBUG
|
||||
std::set<SharedSurface*> mSurfaces;
|
||||
#endif
|
||||
UniquePtrQueue<SharedSurface> mScraps;
|
||||
mutable Monitor mMonitor;
|
||||
bool mIsAlive;
|
||||
|
||||
// Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update()
|
||||
// before sent up to the compositor. You have been warned (Bug 894405)
|
||||
mozilla::gl::GLContext* mGLContext;
|
||||
|
||||
// |previous| can be null, indicating this is the first one.
|
||||
// Otherwise, we pull in |mProd| from |previous| an our initial surface.
|
||||
SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream);
|
||||
|
||||
public:
|
||||
virtual ~SurfaceStream();
|
||||
|
||||
protected:
|
||||
// These functions below are helpers to make trading buffers around easier.
|
||||
// For instance, using Move(a,b) instead of normal assignment assures that
|
||||
// we are never leaving anything hanging around, keeping things very safe.
|
||||
void MoveTo(UniquePtr<SharedSurface>* slotFrom,
|
||||
UniquePtr<SharedSurface>* slotTo);
|
||||
void New(SurfaceFactory* factory, const gfx::IntSize& size,
|
||||
UniquePtr<SharedSurface>* surfSlot);
|
||||
void Delete(UniquePtr<SharedSurface>* surfSlot);
|
||||
void Recycle(SurfaceFactory* factory,
|
||||
UniquePtr<SharedSurface>* surfSlot);
|
||||
|
||||
// Surrender control of a surface, and return it for use elsewhere.
|
||||
UniquePtr<SharedSurface> Surrender(UniquePtr<SharedSurface>* surfSlot);
|
||||
// Absorb control of a surface from elsewhere, clears its old location.
|
||||
UniquePtr<SharedSurface> Absorb(UniquePtr<SharedSurface>* surfSlot);
|
||||
|
||||
// For holding on to surfaces we don't need until we can return them to the
|
||||
// Producer's factory via SurfaceFactory::Recycle.
|
||||
// Not thread-safe.
|
||||
void Scrap(UniquePtr<SharedSurface>* surfSlot);
|
||||
|
||||
// Not thread-safe.
|
||||
void RecycleScraps(SurfaceFactory* factory);
|
||||
|
||||
public:
|
||||
/* Note that ownership of the returned surfaces below
|
||||
* transfers to the caller.
|
||||
* SwapProd returns null on failure. Returning null doesn't mean nothing
|
||||
* happened, but rather that a surface allocation failed. After returning
|
||||
* null, we must be able to call SwapProducer again with better args
|
||||
* and have everything work again.
|
||||
* One common failure is asking for a too-large |size|.
|
||||
*/
|
||||
virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size) = 0;
|
||||
|
||||
virtual SharedSurface* Resize(SurfaceFactory* factory, const gfx::IntSize& size);
|
||||
|
||||
virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory) { MOZ_ASSERT(0); return false; }
|
||||
|
||||
protected:
|
||||
// SwapCons will return the same surface more than once,
|
||||
// if nothing new has been published.
|
||||
virtual SharedSurface* SwapConsumer_NoWait() = 0;
|
||||
|
||||
public:
|
||||
virtual SharedSurface* SwapConsumer();
|
||||
|
||||
virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer) = 0;
|
||||
};
|
||||
|
||||
// Not thread-safe. Don't use cross-threads.
|
||||
class SurfaceStream_SingleBuffer
|
||||
: public SurfaceStream
|
||||
{
|
||||
protected:
|
||||
UniquePtr<SharedSurface> mConsumer; // Only present after resize-swap.
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer)
|
||||
|
||||
explicit SurfaceStream_SingleBuffer(SurfaceStream* prevStream);
|
||||
virtual ~SurfaceStream_SingleBuffer();
|
||||
|
||||
/* Since we're non-OMTC, we know the order of execution here:
|
||||
* SwapProd gets called in UpdateSurface, followed by
|
||||
* SwapCons being called in Render.
|
||||
*/
|
||||
virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size) MOZ_OVERRIDE;
|
||||
|
||||
virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
// Our hero for preserveDrawingBuffer=true.
|
||||
class SurfaceStream_TripleBuffer_Copy
|
||||
: public SurfaceStream
|
||||
{
|
||||
protected:
|
||||
UniquePtr<SharedSurface> mStaging;
|
||||
UniquePtr<SharedSurface> mConsumer;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy)
|
||||
|
||||
explicit SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream);
|
||||
virtual ~SurfaceStream_TripleBuffer_Copy();
|
||||
|
||||
virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size) MOZ_OVERRIDE;
|
||||
|
||||
virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
class SurfaceStream_TripleBuffer
|
||||
: public SurfaceStream
|
||||
{
|
||||
protected:
|
||||
UniquePtr<SharedSurface> mStaging;
|
||||
UniquePtr<SharedSurface> mConsumer;
|
||||
|
||||
// Returns true if we were able to wait, false if not
|
||||
virtual void WaitForCompositor() {}
|
||||
|
||||
// To support subclasses initializing the mType.
|
||||
SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer)
|
||||
|
||||
explicit SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
|
||||
virtual ~SurfaceStream_TripleBuffer();
|
||||
|
||||
virtual bool CopySurfaceToProducer(SharedSurface* src,
|
||||
SurfaceFactory* factory) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
// Common constructor code.
|
||||
void Init(SurfaceStream* prevStream);
|
||||
|
||||
public:
|
||||
// Done writing to prod, swap prod and staging
|
||||
virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
|
||||
const gfx::IntSize& size) MOZ_OVERRIDE;
|
||||
|
||||
virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
|
||||
UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
class SurfaceStream_TripleBuffer_Async
|
||||
: public SurfaceStream_TripleBuffer
|
||||
{
|
||||
protected:
|
||||
virtual void WaitForCompositor() MOZ_OVERRIDE;
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Async)
|
||||
|
||||
explicit SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream);
|
||||
virtual ~SurfaceStream_TripleBuffer_Async();
|
||||
};
|
||||
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // SURFACESTREAM_H_
|
|
@ -47,7 +47,7 @@ SurfaceCaps::Clear()
|
|||
depth = false;
|
||||
stencil = false;
|
||||
antialias = false;
|
||||
premultAlpha = false;
|
||||
premultAlpha = true;
|
||||
preserve = false;
|
||||
surfaceAllocator = nullptr;
|
||||
}
|
||||
|
|
|
@ -82,16 +82,6 @@ MOZ_BEGIN_ENUM_CLASS(SharedSurfaceType, uint8_t)
|
|||
Max
|
||||
MOZ_END_ENUM_CLASS(SharedSurfaceType)
|
||||
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(SurfaceStreamType, uint8_t)
|
||||
SingleBuffer,
|
||||
TripleBuffer_Copy,
|
||||
TripleBuffer_Async,
|
||||
TripleBuffer,
|
||||
Max
|
||||
MOZ_END_ENUM_CLASS(SurfaceStreamType)
|
||||
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(AttachmentType, uint8_t)
|
||||
Screen = 0,
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ EXPORTS += [
|
|||
'SharedSurface.h',
|
||||
'SharedSurfaceEGL.h',
|
||||
'SharedSurfaceGL.h',
|
||||
'SurfaceStream.h',
|
||||
'SurfaceTypes.h',
|
||||
'TextureGarbageBin.h',
|
||||
]
|
||||
|
@ -134,7 +133,6 @@ UNIFIED_SOURCES += [
|
|||
'SharedSurface.cpp',
|
||||
'SharedSurfaceEGL.cpp',
|
||||
'SharedSurfaceGL.cpp',
|
||||
'SurfaceStream.cpp',
|
||||
'SurfaceTypes.cpp',
|
||||
'TextureGarbageBin.cpp',
|
||||
'TextureImageEGL.cpp',
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "GLScreenBuffer.h" // for GLScreenBuffer
|
||||
#include "SharedSurface.h" // for SharedSurface
|
||||
#include "SharedSurfaceGL.h" // for SharedSurface
|
||||
#include "SurfaceStream.h" // for SurfaceStream
|
||||
#include "gfxPattern.h" // for gfxPattern, etc
|
||||
#include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat
|
||||
#include "gfxRect.h" // for gfxRect
|
||||
|
@ -31,7 +30,7 @@ using namespace mozilla::gl;
|
|||
|
||||
CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
|
||||
CanvasLayer(aLayerManager, aImplData)
|
||||
, mStream(nullptr)
|
||||
, mGLFrontbuffer(nullptr)
|
||||
, mIsAlphaPremultiplied(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CopyableCanvasLayer);
|
||||
|
@ -49,13 +48,18 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
|||
|
||||
if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mStream = aData.mStream;
|
||||
mIsAlphaPremultiplied = aData.mIsGLAlphaPremult;
|
||||
mNeedsYFlip = true;
|
||||
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
|
||||
|
||||
// [Basic Layers, non-OMTC] WebGL layer init.
|
||||
// `GLScreenBuffer::Morph`ing is only needed in BasicShadowableCanvasLayer.
|
||||
if (aData.mFrontbufferGLTex) {
|
||||
gfx::IntSize size(aData.mSize.width, aData.mSize.height);
|
||||
mGLFrontbuffer = SharedSurface_GLTexture::Create(aData.mGLContext,
|
||||
nullptr,
|
||||
aData.mGLContext->GetGLFormats(),
|
||||
size, aData.mHasAlpha,
|
||||
aData.mFrontbufferGLTex);
|
||||
}
|
||||
} else if (aData.mDrawTarget) {
|
||||
mDrawTarget = aData.mDrawTarget;
|
||||
mSurface = mDrawTarget->Snapshot();
|
||||
|
@ -70,7 +74,7 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
|||
bool
|
||||
CopyableCanvasLayer::IsDataValid(const Data& aData)
|
||||
{
|
||||
return mGLContext == aData.mGLContext && mStream == aData.mStream;
|
||||
return mGLContext == aData.mGLContext;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -96,77 +100,76 @@ CopyableCanvasLayer::UpdateTarget(DrawTarget* aDestTarget)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mGLContext) {
|
||||
SharedSurface* sharedSurf = nullptr;
|
||||
if (mStream) {
|
||||
sharedSurf = mStream->SwapConsumer();
|
||||
} else {
|
||||
auto screen = mGLContext->Screen();
|
||||
sharedSurf = screen->Front()->Surf();
|
||||
if (mDrawTarget)
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(mGLContext);
|
||||
|
||||
SharedSurface* frontbuffer = nullptr;
|
||||
if (mGLFrontbuffer) {
|
||||
frontbuffer = mGLFrontbuffer.get();
|
||||
} else {
|
||||
auto screen = mGLContext->Screen();
|
||||
auto front = screen->Front();
|
||||
if (front) {
|
||||
frontbuffer = front->Surf();
|
||||
}
|
||||
}
|
||||
|
||||
if (!sharedSurf) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
if (!frontbuffer) {
|
||||
NS_WARNING("Null frame received.");
|
||||
return;
|
||||
}
|
||||
|
||||
IntSize readSize(sharedSurf->mSize);
|
||||
SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? SurfaceFormat::B8G8R8X8
|
||||
: SurfaceFormat::B8G8R8A8;
|
||||
bool needsPremult = sharedSurf->mHasAlpha && !mIsAlphaPremultiplied;
|
||||
IntSize readSize(frontbuffer->mSize);
|
||||
SurfaceFormat format = (GetContentFlags() & CONTENT_OPAQUE)
|
||||
? SurfaceFormat::B8G8R8X8
|
||||
: SurfaceFormat::B8G8R8A8;
|
||||
bool needsPremult = frontbuffer->mHasAlpha && !mIsAlphaPremultiplied;
|
||||
|
||||
// Try to read back directly into aDestTarget's output buffer
|
||||
if (aDestTarget) {
|
||||
uint8_t* destData;
|
||||
IntSize destSize;
|
||||
int32_t destStride;
|
||||
SurfaceFormat destFormat;
|
||||
if (aDestTarget->LockBits(&destData, &destSize, &destStride, &destFormat)) {
|
||||
if (destSize == readSize && destFormat == format) {
|
||||
RefPtr<DataSourceSurface> data =
|
||||
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
|
||||
mGLContext->Screen()->Readback(sharedSurf, data);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
}
|
||||
aDestTarget->ReleaseBits(destData);
|
||||
return;
|
||||
// Try to read back directly into aDestTarget's output buffer
|
||||
if (aDestTarget) {
|
||||
uint8_t* destData;
|
||||
IntSize destSize;
|
||||
int32_t destStride;
|
||||
SurfaceFormat destFormat;
|
||||
if (aDestTarget->LockBits(&destData, &destSize, &destStride, &destFormat)) {
|
||||
if (destSize == readSize && destFormat == format) {
|
||||
RefPtr<DataSourceSurface> data =
|
||||
Factory::CreateWrappingDataSourceSurface(destData, destStride, destSize, destFormat);
|
||||
mGLContext->Screen()->Readback(frontbuffer, data);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
}
|
||||
aDestTarget->ReleaseBits(destData);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> resultSurf;
|
||||
if (sharedSurf->mType == SharedSurfaceType::Basic && !needsPremult) {
|
||||
SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(sharedSurf);
|
||||
resultSurf = sharedSurf_Basic->GetData();
|
||||
} else {
|
||||
RefPtr<DataSourceSurface> data = GetTempSurface(readSize, format);
|
||||
// There will already be a warning from inside of GetTempSurface, but
|
||||
// it doesn't hurt to complain:
|
||||
if (NS_WARN_IF(!data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Screen()->Readback(sharedSurf, data);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(data, data);
|
||||
}
|
||||
resultSurf = data;
|
||||
aDestTarget->ReleaseBits(destData);
|
||||
}
|
||||
MOZ_ASSERT(resultSurf);
|
||||
}
|
||||
|
||||
if (aDestTarget) {
|
||||
aDestTarget->CopySurface(resultSurf,
|
||||
IntRect(0, 0, readSize.width, readSize.height),
|
||||
IntPoint(0, 0));
|
||||
} else {
|
||||
// If !aDestSurface then we will end up painting using mSurface, so
|
||||
// stick our surface into mSurface, so that the Paint() path is the same.
|
||||
mSurface = resultSurf;
|
||||
}
|
||||
RefPtr<DataSourceSurface> resultSurf = GetTempSurface(readSize, format);
|
||||
// There will already be a warning from inside of GetTempSurface, but
|
||||
// it doesn't hurt to complain:
|
||||
if (NS_WARN_IF(!resultSurf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Readback handles Flush/MarkDirty.
|
||||
mGLContext->Screen()->Readback(frontbuffer, resultSurf);
|
||||
if (needsPremult) {
|
||||
gfxUtils::PremultiplyDataSurface(resultSurf, resultSurf);
|
||||
}
|
||||
MOZ_ASSERT(resultSurf);
|
||||
|
||||
if (aDestTarget) {
|
||||
aDestTarget->CopySurface(resultSurf,
|
||||
IntRect(0, 0, readSize.width, readSize.height),
|
||||
IntPoint(0, 0));
|
||||
} else {
|
||||
// If !aDestSurface then we will end up painting using mSurface, so
|
||||
// stick our surface into mSurface, so that the Paint() path is the same.
|
||||
mSurface = resultSurf;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl{
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CanvasClientWebGL;
|
||||
|
@ -53,11 +49,10 @@ protected:
|
|||
|
||||
RefPtr<gfx::SourceSurface> mSurface;
|
||||
nsRefPtr<gl::GLContext> mGLContext;
|
||||
GLuint mCanvasFrontbufferTexID;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
RefPtr<gl::SurfaceStream> mStream;
|
||||
|
||||
uint32_t mCanvasFramebuffer;
|
||||
UniquePtr<gl::SharedSurface> mGLFrontbuffer;
|
||||
|
||||
bool mIsAlphaPremultiplied;
|
||||
bool mNeedsYFlip;
|
||||
|
|
|
@ -59,7 +59,7 @@ class WebGLContext;
|
|||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SurfaceStream;
|
||||
class SharedSurface;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
|
@ -2010,8 +2010,7 @@ public:
|
|||
Data()
|
||||
: mDrawTarget(nullptr)
|
||||
, mGLContext(nullptr)
|
||||
, mStream(nullptr)
|
||||
, mTexID(0)
|
||||
, mFrontbufferGLTex(0)
|
||||
, mSize(0,0)
|
||||
, mHasAlpha(false)
|
||||
, mIsGLAlphaPremult(true)
|
||||
|
@ -2021,11 +2020,8 @@ public:
|
|||
mozilla::gfx::DrawTarget* mDrawTarget; // a DrawTarget for the canvas contents
|
||||
mozilla::gl::GLContext* mGLContext; // or this, for GL.
|
||||
|
||||
// Canvas/SkiaGL uses this
|
||||
mozilla::gl::SurfaceStream* mStream;
|
||||
|
||||
// ID of the texture backing the canvas layer (defaults to 0)
|
||||
uint32_t mTexID;
|
||||
// Frontbuffer override
|
||||
uint32_t mFrontbufferGLTex;
|
||||
|
||||
// The size of the canvas content
|
||||
nsIntSize mSize;
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include "GLContext.h" // for GLContext
|
||||
#include "GLScreenBuffer.h" // for GLScreenBuffer
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SurfaceStream.h" // for SurfaceStream
|
||||
#include "SurfaceTypes.h" // for SurfaceStreamHandle
|
||||
#include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "GLReadTexImageHelper.h"
|
||||
|
@ -50,10 +48,6 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType,
|
|||
case CanvasClientTypeShSurf:
|
||||
return new CanvasClientSharedSurface(aForwarder, aFlags);
|
||||
|
||||
case CanvasClientGLContext:
|
||||
aFlags |= TextureFlags::DEALLOCATE_CLIENT;
|
||||
return new CanvasClientSurfaceStream(aForwarder, aFlags);
|
||||
|
||||
default:
|
||||
return new CanvasClient2D(aForwarder, aFlags);
|
||||
}
|
||||
|
@ -147,13 +141,7 @@ CanvasClient2D::CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
|
|||
mTextureInfo.mTextureFlags | aFlags);
|
||||
#endif
|
||||
}
|
||||
|
||||
CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder,
|
||||
TextureFlags aFlags)
|
||||
: CanvasClient(aLayerForwarder, aFlags)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
|
@ -237,6 +225,7 @@ CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
|||
|
||||
aLayer->Painted();
|
||||
}
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -423,20 +412,35 @@ TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
|
|||
|
||||
////////////////////////////////////////
|
||||
|
||||
static TemporaryRef<gl::ShSurfHandle>
|
||||
CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
|
||||
{
|
||||
RefPtr<gl::ShSurfHandle> dest = factory->NewShSurfHandle(src->mSize);
|
||||
SharedSurface::ProdCopy(src, dest->Surf(), factory);
|
||||
return dest.forget();
|
||||
}
|
||||
|
||||
void
|
||||
CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
aLayer->mGLContext->MakeCurrent();
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
|
||||
if (mFront) {
|
||||
mPrevFront = mFront;
|
||||
mFront = nullptr;
|
||||
}
|
||||
|
||||
mFront = screen->Front();
|
||||
if (!mFront)
|
||||
return;
|
||||
auto gl = aLayer->mGLContext;
|
||||
gl->MakeCurrent();
|
||||
|
||||
if (aLayer->mGLFrontbuffer) {
|
||||
mFront = CloneSurface(aLayer->mGLFrontbuffer.get(), aLayer->mFactory.get());
|
||||
if (mFront)
|
||||
mFront->Surf()->Fence();
|
||||
} else {
|
||||
mFront = gl->Screen()->Front();
|
||||
if (!mFront)
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mFront);
|
||||
|
||||
// Alright, now sort out the IPC goop.
|
||||
SharedSurface* surf = mFront->Surf();
|
||||
|
|
|
@ -112,34 +112,6 @@ private:
|
|||
RefPtr<TextureClient> mBuffer;
|
||||
};
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
// GL backend.
|
||||
class CanvasClientSurfaceStream : public CanvasClient
|
||||
{
|
||||
public:
|
||||
CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder, TextureFlags aFlags);
|
||||
|
||||
TextureInfo GetTextureInfo() const
|
||||
{
|
||||
return TextureInfo(CompositableType::IMAGE);
|
||||
}
|
||||
|
||||
virtual void Clear() MOZ_OVERRIDE
|
||||
{
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) MOZ_OVERRIDE;
|
||||
|
||||
virtual void OnDetach() MOZ_OVERRIDE
|
||||
{
|
||||
mBuffer = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<TextureClient> mBuffer;
|
||||
};
|
||||
|
||||
// Used for GL canvases where we don't need to do any readback, i.e., with a
|
||||
// GL backend.
|
||||
class CanvasClientSharedSurface : public CanvasClient
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
#include "GeckoProfiler.h" // for PROFILER_LABEL
|
||||
#include "SharedSurfaceEGL.h" // for SurfaceFactory_EGLImage
|
||||
#include "SharedSurfaceGL.h" // for SurfaceFactory_GLTexture, etc
|
||||
#include "SurfaceStream.h" // for SurfaceStream, etc
|
||||
#include "SurfaceTypes.h" // for SurfaceStreamType
|
||||
#include "ClientLayerManager.h" // for ClientLayerManager, etc
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
|
@ -46,9 +44,6 @@ ClientCanvasLayer::~ClientCanvasLayer()
|
|||
mCanvasClient->OnDetach();
|
||||
mCanvasClient = nullptr;
|
||||
}
|
||||
if (mTextureSurface) {
|
||||
mTextureSurface = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -58,92 +53,85 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
|
||||
mCanvasClient = nullptr;
|
||||
|
||||
if (mGLContext) {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
if (!mGLContext)
|
||||
return;
|
||||
|
||||
SurfaceCaps caps;
|
||||
if (mStream) {
|
||||
// The screen caps are irrelevant if we're using a separate stream
|
||||
caps = aData.mHasAlpha ? SurfaceCaps::ForRGBA() : SurfaceCaps::ForRGB();
|
||||
} else {
|
||||
caps = screen->mCaps;
|
||||
}
|
||||
MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
SurfaceCaps caps;
|
||||
if (mGLFrontbuffer) {
|
||||
// The screen caps are irrelevant if we're using a separate frontbuffer.
|
||||
caps = mGLFrontbuffer->mHasAlpha ? SurfaceCaps::ForRGBA()
|
||||
: SurfaceCaps::ForRGB();
|
||||
} else {
|
||||
MOZ_ASSERT(screen);
|
||||
caps = screen->mCaps;
|
||||
}
|
||||
MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
|
||||
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
if (mGLContext->GetContextType() == GLContextType::EGL) {
|
||||
UniquePtr<SurfaceFactory> factory;
|
||||
|
||||
if (!gfxPrefs::WebGLForceLayersReadback()) {
|
||||
switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
|
||||
case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
|
||||
if (mGLContext->GetContextType() == GLContextType::EGL) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
|
||||
TextureFlags::NEEDS_Y_FLIP;
|
||||
if (!aData.mIsGLAlphaPremult) {
|
||||
flags |= TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
|
||||
caps,
|
||||
flags,
|
||||
ClientManager()->AsShadowForwarder());
|
||||
TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT |
|
||||
TextureFlags::NEEDS_Y_FLIP;
|
||||
if (!aData.mIsGLAlphaPremult) {
|
||||
flags |= TextureFlags::NON_PREMULTIPLIED;
|
||||
}
|
||||
factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
|
||||
caps,
|
||||
flags,
|
||||
ClientManager()->AsShadowForwarder());
|
||||
#else
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
|
||||
} else {
|
||||
// we could do readback here maybe
|
||||
NS_NOTREACHED("isCrossProcess but not on native B2G!");
|
||||
}
|
||||
#endif
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
// we could do readback here maybe
|
||||
NS_NOTREACHED("isCrossProcess but not on native B2G!");
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
#ifdef XP_MACOSX
|
||||
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps);
|
||||
factory = SurfaceFactory_IOSurface::Create(mGLContext, caps);
|
||||
#else
|
||||
GLContext* nullConsGL = nullptr; // Bug 1050044.
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps);
|
||||
GLContext* nullConsGL = nullptr; // Bug 1050044.
|
||||
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D10:
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
break;
|
||||
}
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D10:
|
||||
case mozilla::layers::LayersBackend::LAYERS_D3D11: {
|
||||
#ifdef XP_WIN
|
||||
if (mGLContext->IsANGLE()) {
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
if (mGLContext->IsANGLE()) {
|
||||
factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mStream) {
|
||||
// We're using a stream other than the one in the default screen
|
||||
mFactory = Move(factory);
|
||||
if (!mFactory) {
|
||||
// Absolutely must have a factory here, so create a basic one
|
||||
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
|
||||
}
|
||||
|
||||
gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height);
|
||||
mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext,
|
||||
mGLContext->GetGLFormats(),
|
||||
size, caps.alpha, aData.mTexID);
|
||||
SharedSurface* producer = mStream->SwapProducer(mFactory.get(), size);
|
||||
if (!producer) {
|
||||
// Fallback to basic factory
|
||||
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
|
||||
producer = mStream->SwapProducer(mFactory.get(), size);
|
||||
MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory");
|
||||
}
|
||||
} else if (factory) {
|
||||
if (mGLFrontbuffer) {
|
||||
// We're using a source other than the one in the default screen.
|
||||
// (SkiaGL)
|
||||
mFactory = Move(factory);
|
||||
if (!mFactory) {
|
||||
// Absolutely must have a factory here, so create a basic one
|
||||
mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
|
||||
}
|
||||
} else {
|
||||
if (factory)
|
||||
screen->Morph(Move(factory));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,10 +190,7 @@ CanvasClient::CanvasClientType
|
|||
ClientCanvasLayer::GetCanvasClientType()
|
||||
{
|
||||
if (mGLContext) {
|
||||
if (mGLContext->Screen()) {
|
||||
return CanvasClient::CanvasClientTypeShSurf;
|
||||
}
|
||||
return CanvasClient::CanvasClientGLContext;
|
||||
return CanvasClient::CanvasClientTypeShSurf;
|
||||
}
|
||||
return CanvasClient::CanvasClientSurface;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SurfaceStream;
|
||||
class SharedSurface;
|
||||
class SurfaceFactory;
|
||||
}
|
||||
|
@ -39,8 +38,6 @@ public:
|
|||
explicit ClientCanvasLayer(ClientLayerManager* aLayerManager) :
|
||||
CopyableCanvasLayer(aLayerManager,
|
||||
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()))
|
||||
, mTextureSurface(nullptr)
|
||||
, mFactory(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientCanvasLayer);
|
||||
}
|
||||
|
@ -95,13 +92,10 @@ protected:
|
|||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
|
||||
UniquePtr<gl::SharedSurface> mTextureSurface;
|
||||
UniquePtr<gl::SurfaceFactory> mFactory;
|
||||
|
||||
friend class DeprecatedCanvasClient2D;
|
||||
friend class CanvasClient2D;
|
||||
friend class DeprecatedCanvasClientSurfaceStream;
|
||||
friend class CanvasClientSurfaceStream;
|
||||
friend class CanvasClientSharedSurface;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
#include "mozilla/layers/PTextureChild.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -804,62 +803,6 @@ BufferTextureClient::GetLockedData() const
|
|||
return serializer.GetData();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// StreamTextureClient
|
||||
StreamTextureClient::StreamTextureClient(TextureFlags aFlags)
|
||||
: TextureClient(aFlags)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
}
|
||||
|
||||
StreamTextureClient::~StreamTextureClient()
|
||||
{
|
||||
// the data is owned externally.
|
||||
}
|
||||
|
||||
bool
|
||||
StreamTextureClient::Lock(OpenMode mode)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StreamTextureClient::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
bool
|
||||
StreamTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = SurfaceStreamDescriptor((uintptr_t)mStream.get(), false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StreamTextureClient::InitWith(gl::SurfaceStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mStream = aStream;
|
||||
mGL = mStream->GLContext();
|
||||
}
|
||||
|
||||
bool
|
||||
StreamTextureClient::IsAllocated() const
|
||||
{
|
||||
return mStream != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SharedSurfaceTextureClient
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace mozilla {
|
|||
namespace gl {
|
||||
class GLContext;
|
||||
class SharedSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
@ -628,57 +627,6 @@ protected:
|
|||
size_t mBufSize;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureClient implementation to share SurfaceStream.
|
||||
*/
|
||||
class StreamTextureClient : public TextureClient
|
||||
{
|
||||
public:
|
||||
explicit StreamTextureClient(TextureFlags aFlags);
|
||||
|
||||
protected:
|
||||
~StreamTextureClient();
|
||||
|
||||
public:
|
||||
virtual bool IsAllocated() const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool Lock(OpenMode mode) MOZ_OVERRIDE;
|
||||
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool IsLocked() const MOZ_OVERRIDE { return mIsLocked; }
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; }
|
||||
|
||||
void InitWith(gl::SurfaceStream* aStream);
|
||||
|
||||
virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
|
||||
{
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
|
||||
// This TextureClient should not be used in a context where we use CreateSimilar
|
||||
// (ex. component alpha) because the underlying texture data is always created by
|
||||
// an external producer.
|
||||
virtual TemporaryRef<TextureClient>
|
||||
CreateSimilar(TextureFlags, TextureAllocationFlags) const MOZ_OVERRIDE { return nullptr; }
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool mIsLocked;
|
||||
RefPtr<gl::SurfaceStream> mStream;
|
||||
RefPtr<gl::GLContext> mGL; // Just for reference holding.
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureClient implementation to share SharedSurfaces.
|
||||
*/
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceEGL.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "../opengl/CompositorOGL.h"
|
||||
|
||||
#ifdef MOZ_ENABLE_D3D10_LAYER
|
||||
|
@ -200,9 +199,6 @@ TextureHost::Create(const SurfaceDescriptor& aDesc,
|
|||
case SurfaceDescriptor::TSurfaceTextureDescriptor:
|
||||
return CreateTextureHostOGL(aDesc, aDeallocator, aFlags);
|
||||
|
||||
case SurfaceDescriptor::TSurfaceStreamDescriptor:
|
||||
return new StreamTextureHost(aFlags, aDesc.get_SurfaceStreamDescriptor());
|
||||
|
||||
case SurfaceDescriptor::TSharedSurfaceDescriptor:
|
||||
return new SharedSurfaceTextureHost(aFlags, aDesc.get_SharedSurfaceDescriptor());
|
||||
|
||||
|
@ -799,207 +795,6 @@ TextureParent::ClearTextureHost()
|
|||
mTextureHost = nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// StreamTextureHost
|
||||
|
||||
StreamTextureHost::StreamTextureHost(TextureFlags aFlags,
|
||||
const SurfaceStreamDescriptor& aDesc)
|
||||
: TextureHost(aFlags)
|
||||
{
|
||||
mStream = (gl::SurfaceStream*)aDesc.surfStream();
|
||||
MOZ_ASSERT(mStream);
|
||||
}
|
||||
|
||||
StreamTextureHost::~StreamTextureHost()
|
||||
{
|
||||
// If need to deallocate textures, call DeallocateSharedData() before
|
||||
// the destructor
|
||||
}
|
||||
|
||||
bool
|
||||
StreamTextureHost::Lock()
|
||||
{
|
||||
if (!mCompositor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gl::SharedSurface* abstractSurf = mStream->SwapConsumer();
|
||||
if (!abstractSurf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool compositorSupportsShSurfType = false;
|
||||
switch (mCompositor->GetBackendType()) {
|
||||
case LayersBackend::LAYERS_BASIC:
|
||||
case LayersBackend::LAYERS_D3D9:
|
||||
case LayersBackend::LAYERS_D3D10:
|
||||
switch (abstractSurf->mType) {
|
||||
case gl::SharedSurfaceType::Basic:
|
||||
compositorSupportsShSurfType = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LayersBackend::LAYERS_OPENGL:
|
||||
switch (abstractSurf->mType) {
|
||||
case gl::SharedSurfaceType::Basic:
|
||||
case gl::SharedSurfaceType::GLTextureShare:
|
||||
case gl::SharedSurfaceType::EGLImageShare:
|
||||
case gl::SharedSurfaceType::Gralloc:
|
||||
case gl::SharedSurfaceType::IOSurface:
|
||||
compositorSupportsShSurfType = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LayersBackend::LAYERS_D3D11:
|
||||
switch (abstractSurf->mType) {
|
||||
case gl::SharedSurfaceType::Basic:
|
||||
case gl::SharedSurfaceType::EGLSurfaceANGLE:
|
||||
compositorSupportsShSurfType = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
RefPtr<TextureSource> newTexSource;
|
||||
if (compositorSupportsShSurfType) {
|
||||
gfx::SurfaceFormat format = abstractSurf->mHasAlpha ? gfx::SurfaceFormat::R8G8B8A8
|
||||
: gfx::SurfaceFormat::R8G8B8X8;
|
||||
|
||||
switch (abstractSurf->mType) {
|
||||
case gl::SharedSurfaceType::Basic: {
|
||||
gl::SharedSurface_Basic* surf = gl::SharedSurface_Basic::Cast(abstractSurf);
|
||||
|
||||
if (!this->mDataTextureSource) {
|
||||
TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT;
|
||||
this->mDataTextureSource = mCompositor->CreateDataTextureSource(flags);
|
||||
}
|
||||
this->mDataTextureSource->Update(surf->GetData());
|
||||
|
||||
newTexSource = mDataTextureSource;
|
||||
break;
|
||||
}
|
||||
case gl::SharedSurfaceType::GLTextureShare: {
|
||||
gl::SharedSurface_GLTexture* surf = gl::SharedSurface_GLTexture::Cast(abstractSurf);
|
||||
|
||||
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
|
||||
gl::GLContext* gl = compositorOGL->gl();
|
||||
|
||||
GLenum target = surf->ConsTextureTarget();
|
||||
GLuint tex = surf->ConsTexture(gl);
|
||||
newTexSource = new GLTextureSource(compositorOGL,
|
||||
tex,
|
||||
format,
|
||||
target,
|
||||
surf->mSize);
|
||||
break;
|
||||
}
|
||||
#ifdef MOZ_ENABLE_D3D10_LAYER
|
||||
case gl::SharedSurfaceType::EGLSurfaceANGLE: {
|
||||
gl::SharedSurface_ANGLEShareHandle* surf = gl::SharedSurface_ANGLEShareHandle::Cast(abstractSurf);
|
||||
HANDLE shareHandle = surf->GetShareHandle();
|
||||
|
||||
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_D3D11);
|
||||
CompositorD3D11* compositorD3D11 = static_cast<CompositorD3D11*>(mCompositor);
|
||||
ID3D11Device* d3d = compositorD3D11->GetDevice();
|
||||
|
||||
nsRefPtr<ID3D11Texture2D> tex;
|
||||
HRESULT hr = d3d->OpenSharedResource(shareHandle,
|
||||
__uuidof(ID3D11Texture2D),
|
||||
getter_AddRefs(tex));
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to open shared resource.");
|
||||
break;
|
||||
}
|
||||
newTexSource = new DataTextureSourceD3D11(format, compositorD3D11, tex);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case gl::SharedSurfaceType::EGLImageShare: {
|
||||
gl::SharedSurface_EGLImage* surf = gl::SharedSurface_EGLImage::Cast(abstractSurf);
|
||||
|
||||
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
|
||||
gl::GLContext* gl = compositorOGL->gl();
|
||||
MOZ_ASSERT(gl->IsCurrent());
|
||||
|
||||
GLenum target = 0;
|
||||
GLuint tex = 0;
|
||||
surf->AcquireConsumerTexture(gl, &tex, &target);
|
||||
|
||||
newTexSource = new GLTextureSource(compositorOGL,
|
||||
tex,
|
||||
format,
|
||||
target,
|
||||
surf->mSize);
|
||||
break;
|
||||
}
|
||||
case gl::SharedSurfaceType::Gralloc: {
|
||||
MOZ_ASSERT(false, "WebGL in the Host process? Gralloc without E10S? Not yet supported.");
|
||||
break;
|
||||
}
|
||||
#ifdef XP_MACOSX
|
||||
case gl::SharedSurfaceType::IOSurface: {
|
||||
gl::SharedSurface_IOSurface* surf = gl::SharedSurface_IOSurface::Cast(abstractSurf);
|
||||
MacIOSurface* ioSurf = surf->GetIOSurface();
|
||||
|
||||
MOZ_ASSERT(mCompositor->GetBackendType() == LayersBackend::LAYERS_OPENGL);
|
||||
CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(mCompositor);
|
||||
|
||||
newTexSource = new MacIOSurfaceTextureSourceOGL(compositorOGL,
|
||||
ioSurf);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Do readback, and make a buffer view for it?
|
||||
NS_WARNING("`!compositorSupportsShSurfType`.");
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(newTexSource.get(), "TextureSource creation failed.");
|
||||
if (!newTexSource)
|
||||
return false;
|
||||
|
||||
mTextureSource = newTexSource;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
StreamTextureHost::Unlock()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
StreamTextureHost::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = aCompositor;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
StreamTextureHost::GetFormat() const
|
||||
{
|
||||
MOZ_ASSERT(mTextureSource);
|
||||
return mTextureSource->GetFormat();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
StreamTextureHost::GetSize() const
|
||||
{
|
||||
MOZ_ASSERT(mTextureSource);
|
||||
return mTextureSource->GetSize();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static RefPtr<NewTextureSource>
|
||||
|
|
|
@ -36,7 +36,6 @@ struct nsIntRect;
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SharedSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
namespace ipc {
|
||||
class Shmem;
|
||||
|
@ -49,7 +48,6 @@ class CompositableHost;
|
|||
class CompositableBackendSpecificData;
|
||||
class CompositableParentManager;
|
||||
class SurfaceDescriptor;
|
||||
class SurfaceStreamDescriptor;
|
||||
class SharedSurfaceDescriptor;
|
||||
class ISurfaceAllocator;
|
||||
class TextureHostOGL;
|
||||
|
@ -573,50 +571,6 @@ protected:
|
|||
uint8_t* mBuffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for shared SurfaceStream
|
||||
*/
|
||||
class StreamTextureHost : public TextureHost
|
||||
{
|
||||
public:
|
||||
StreamTextureHost(TextureFlags aFlags,
|
||||
const SurfaceStreamDescriptor& aDesc);
|
||||
|
||||
virtual ~StreamTextureHost();
|
||||
|
||||
virtual void DeallocateDeviceData() MOZ_OVERRIDE {};
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool Lock() MOZ_OVERRIDE;
|
||||
|
||||
virtual void Unlock() MOZ_OVERRIDE;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
|
||||
|
||||
virtual TextureSource* GetTextureSources() MOZ_OVERRIDE
|
||||
{
|
||||
return mTextureSource;
|
||||
}
|
||||
|
||||
virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE
|
||||
{
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() { return "StreamTextureHost"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Compositor* mCompositor;
|
||||
gl::SurfaceStream* mStream;
|
||||
RefPtr<TextureSource> mTextureSource;
|
||||
RefPtr<DataTextureSource> mDataTextureSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for SharedSurfaces
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "../d3d9/Nv3DVUtils.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurfaceANGLE.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "gfxContext.h"
|
||||
|
|
|
@ -154,9 +154,6 @@ CreateTextureHostD3D11(const SurfaceDescriptor& aDesc,
|
|||
aDesc.get_SurfaceDescriptorD3D10());
|
||||
break;
|
||||
}
|
||||
case SurfaceDescriptor::TSurfaceStreamDescriptor: {
|
||||
MOZ_CRASH("Should never hit this.");
|
||||
}
|
||||
default: {
|
||||
NS_WARNING("Unsupported SurfaceDescriptor type");
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "GLContext.h"
|
||||
|
|
|
@ -76,11 +76,6 @@ struct NewSurfaceDescriptorGralloc {
|
|||
IntSize size;
|
||||
};
|
||||
|
||||
struct SurfaceStreamDescriptor {
|
||||
uintptr_t surfStream;
|
||||
bool yflip;
|
||||
};
|
||||
|
||||
struct SharedSurfaceDescriptor {
|
||||
uintptr_t surf;
|
||||
};
|
||||
|
@ -110,7 +105,6 @@ union SurfaceDescriptor {
|
|||
SurfaceDescriptorX11;
|
||||
SurfaceTextureDescriptor;
|
||||
EGLImageDescriptor;
|
||||
SurfaceStreamDescriptor;
|
||||
SurfaceDescriptorMacIOSurface;
|
||||
NewSurfaceDescriptorGralloc;
|
||||
SharedSurfaceDescriptor;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GLContext.h" // for GLContext, etc
|
||||
#include "SurfaceStream.h"
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
|
@ -31,15 +30,15 @@ EGLImageTextureClient::EGLImageTextureClient(TextureFlags aFlags,
|
|||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default,
|
||||
"Can't pass an `EGLImage` between processes.");
|
||||
|
||||
|
||||
// Our data is always owned externally.
|
||||
AddFlags(TextureFlags::DEALLOCATE_CLIENT);
|
||||
|
||||
|
||||
if (aInverted) {
|
||||
AddFlags(TextureFlags::NEEDS_Y_FLIP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EGLImageTextureClient::~EGLImageTextureClient()
|
||||
{
|
||||
// Our data is always owned externally.
|
||||
|
@ -65,14 +64,14 @@ EGLImageTextureClient::Lock(OpenMode mode)
|
|||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
EGLImageTextureClient::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked);
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// SurfaceTextureClient
|
||||
|
||||
|
@ -97,7 +96,7 @@ SurfaceTextureClient::SurfaceTextureClient(TextureFlags aFlags,
|
|||
AddFlags(TextureFlags::NEEDS_Y_FLIP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SurfaceTextureClient::~SurfaceTextureClient()
|
||||
{
|
||||
// Our data is always owned externally.
|
||||
|
|
|
@ -15,12 +15,6 @@
|
|||
#include "mozilla/layers/TextureClient.h" // for TextureClient, etc
|
||||
#include "nsSurfaceTexture.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class SurfaceStream;
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
|
|
@ -48,10 +48,6 @@ namespace gfx {
|
|||
class DataSourceSurface;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class Compositor;
|
||||
|
|
Загрузка…
Ссылка в новой задаче