зеркало из https://github.com/mozilla/gecko-dev.git
Bug 939276 - Use a single GLContext for all SkiaGL canvases r=jgilbert,vlad,gwright,bjacob
--HG-- rename : gfx/gl/GLContextSkia.cpp => gfx/gl/SkiaGLGlue.cpp
This commit is contained in:
Родитель
1fd761ef37
Коммит
dfee0058ef
|
@ -94,14 +94,14 @@
|
|||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
#undef free // apparently defined by some windows header, clashing with a free()
|
||||
// method in SkTypes.h
|
||||
#include "GLContextSkia.h"
|
||||
#include "SkiaGLGlue.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "SurfaceTypes.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#endif
|
||||
|
||||
using mozilla::gl::GLContext;
|
||||
using mozilla::gl::SkiaGLGlue;
|
||||
using mozilla::gl::GLContextProvider;
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
@ -430,28 +430,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static void PreTransactionCallback(void* aData)
|
||||
{
|
||||
CanvasRenderingContext2DUserData* self =
|
||||
static_cast<CanvasRenderingContext2DUserData*>(aData);
|
||||
CanvasRenderingContext2D* context = self->mContext;
|
||||
if (!context)
|
||||
if (!context || !context->mStream || !context->mTarget)
|
||||
return;
|
||||
|
||||
GLContext* glContext = static_cast<GLContext*>(context->mTarget->GetGLContext());
|
||||
if (!glContext)
|
||||
return;
|
||||
|
||||
if (context->mTarget) {
|
||||
// Since SkiaGL default to store drawing command until flush
|
||||
// We will have to flush it before present.
|
||||
context->mTarget->Flush();
|
||||
}
|
||||
glContext->MakeCurrent();
|
||||
glContext->PublishFrame();
|
||||
// Since SkiaGL default to store drawing command until flush
|
||||
// We will have to flush it before present.
|
||||
context->mTarget->Flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void DidTransactionCallback(void* aData)
|
||||
{
|
||||
|
@ -542,18 +532,15 @@ DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
|
|||
|
||||
|
||||
CanvasRenderingContext2D::CanvasRenderingContext2D()
|
||||
: mZero(false), mOpaque(false), mResetLayer(true)
|
||||
: mForceSoftware(false), mZero(false), mOpaque(false), mResetLayer(true)
|
||||
, mIPC(false)
|
||||
, mStream(nullptr)
|
||||
, mIsEntireFrameInvalid(false)
|
||||
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
|
||||
, mInvalidateCount(0)
|
||||
{
|
||||
sNumLivingContexts++;
|
||||
SetIsDOMBinding();
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
mForceSoftware = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
CanvasRenderingContext2D::~CanvasRenderingContext2D()
|
||||
|
@ -568,9 +555,7 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
|
|||
NS_IF_RELEASE(sErrorTarget);
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
RemoveDemotableContext(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
JSObject*
|
||||
|
@ -638,6 +623,7 @@ CanvasRenderingContext2D::Reset()
|
|||
}
|
||||
|
||||
mTarget = nullptr;
|
||||
mStream = nullptr;
|
||||
|
||||
// reset hit regions
|
||||
#ifdef ACCESSIBILITY
|
||||
|
@ -765,8 +751,7 @@ CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
|
|||
|
||||
void CanvasRenderingContext2D::Demote()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (!IsTargetValid() || mForceSoftware || !mTarget->GetGLContext())
|
||||
if (!IsTargetValid() || mForceSoftware || !mStream)
|
||||
return;
|
||||
|
||||
RemoveDemotableContext(this);
|
||||
|
@ -774,6 +759,7 @@ void CanvasRenderingContext2D::Demote()
|
|||
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
|
||||
RefPtr<DrawTarget> oldTarget = mTarget;
|
||||
mTarget = nullptr;
|
||||
mStream = nullptr;
|
||||
mResetLayer = true;
|
||||
mForceSoftware = true;
|
||||
|
||||
|
@ -792,11 +778,8 @@ void CanvasRenderingContext2D::Demote()
|
|||
}
|
||||
|
||||
mTarget->SetTransform(oldTarget->GetTransform());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
|
||||
std::vector<CanvasRenderingContext2D*>&
|
||||
CanvasRenderingContext2D::DemotableContexts()
|
||||
{
|
||||
|
@ -807,11 +790,7 @@ CanvasRenderingContext2D::DemotableContexts()
|
|||
void
|
||||
CanvasRenderingContext2D::DemoteOldestContextIfNecessary()
|
||||
{
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
const size_t kMaxContexts = 2;
|
||||
#else
|
||||
const size_t kMaxContexts = 16;
|
||||
#endif
|
||||
const size_t kMaxContexts = 64;
|
||||
|
||||
std::vector<CanvasRenderingContext2D*>& contexts = DemotableContexts();
|
||||
if (contexts.size() < kMaxContexts)
|
||||
|
@ -845,8 +824,6 @@ CheckSizeForSkiaGL(IntSize size) {
|
|||
return size.width >= minsize && size.height >= minsize;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::EnsureTarget()
|
||||
{
|
||||
|
@ -872,42 +849,29 @@ CanvasRenderingContext2D::EnsureTarget()
|
|||
}
|
||||
|
||||
if (layerManager) {
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas()) {
|
||||
SurfaceCaps caps = SurfaceCaps::ForRGBA();
|
||||
caps.preserve = true;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
layers::ShadowLayerForwarder *forwarder = layerManager->AsShadowForwarder();
|
||||
if (forwarder) {
|
||||
caps.surfaceAllocator = static_cast<layers::ISurfaceAllocator*>(forwarder);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gfxPlatform::GetPlatform()->UseAcceleratedSkiaCanvas() &&
|
||||
!mForceSoftware &&
|
||||
CheckSizeForSkiaGL(size)) {
|
||||
DemoteOldestContextIfNecessary();
|
||||
|
||||
nsRefPtr<GLContext> glContext;
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
nsString vendor;
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
|
||||
if (!mForceSoftware && CheckSizeForSkiaGL(size))
|
||||
{
|
||||
glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height),
|
||||
caps);
|
||||
if (glue) {
|
||||
mTarget = Factory::CreateDrawTargetSkiaWithGrContext(glue->GetGrContext(), size, format);
|
||||
if (mTarget) {
|
||||
mStream = gfx::SurfaceStream::CreateForType(SurfaceStreamType::TripleBuffer, glue->GetGLContext());
|
||||
AddDemotableContext(this);
|
||||
} else {
|
||||
printf_stderr("Failed to create a SkiaGL DrawTarget, falling back to software\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (glContext) {
|
||||
SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(glContext));
|
||||
mTarget = Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(glContext, i, size, format);
|
||||
AddDemotableContext(this);
|
||||
} else {
|
||||
if (!mTarget) {
|
||||
mTarget = layerManager->CreateDrawTarget(size, format);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
mTarget = layerManager->CreateDrawTarget(size, format);
|
||||
mTarget = layerManager->CreateDrawTarget(size, format);
|
||||
} else {
|
||||
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
|
||||
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenCanvasDrawTarget(size, format);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1092,12 +1056,10 @@ CanvasRenderingContext2D::SetContextOptions(JSContext* aCx, JS::Handle<JS::Value
|
|||
ContextAttributes2D attributes;
|
||||
NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
|
||||
// Use software when there is going to be a lot of readback
|
||||
mForceSoftware = attributes.mWillReadFrequently;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3340,7 +3302,6 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
|||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static bool
|
||||
IsStandardCompositeOp(CompositionOp op)
|
||||
{
|
||||
|
@ -3356,7 +3317,6 @@ IsStandardCompositeOp(CompositionOp op)
|
|||
op == CompositionOp::OP_ADD ||
|
||||
op == CompositionOp::OP_XOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
|
||||
|
@ -3397,11 +3357,9 @@ CanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op,
|
|||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
else return;
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (!IsStandardCompositeOp(comp_op)) {
|
||||
Demote();
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef CANVAS_OP_TO_GFX_OP
|
||||
CurrentState().op = comp_op;
|
||||
|
@ -3447,11 +3405,9 @@ CanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op,
|
|||
error.Throw(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (!IsStandardCompositeOp(comp_op)) {
|
||||
Demote();
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef CANVAS_OP_TO_GFX_OP
|
||||
}
|
||||
|
@ -4151,7 +4107,17 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
aOldLayer->GetUserData(&g2DContextLayerUserData));
|
||||
|
||||
CanvasLayer::Data data;
|
||||
data.mGLContext = static_cast<GLContext*>(mTarget->GetGLContext());
|
||||
if (mStream) {
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
|
||||
if (glue) {
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mStream = mStream.get();
|
||||
}
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
}
|
||||
|
||||
if (userData && userData->IsForContext(this) && aOldLayer->IsDataValid(data)) {
|
||||
nsRefPtr<CanvasLayer> ret = aOldLayer;
|
||||
return ret.forget();
|
||||
|
@ -4184,15 +4150,17 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
|
|||
canvasLayer->SetUserData(&g2DContextLayerUserData, userData);
|
||||
|
||||
CanvasLayer::Data data;
|
||||
#ifdef USE_SKIA_GPU
|
||||
GLContext* glContext = static_cast<GLContext*>(mTarget->GetGLContext());
|
||||
if (glContext) {
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
data.mGLContext = glContext;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (mStream) {
|
||||
SkiaGLGlue* glue = gfxPlatform::GetPlatform()->GetSkiaGLGlue();
|
||||
|
||||
if (glue) {
|
||||
canvasLayer->SetPreTransactionCallback(
|
||||
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
|
||||
data.mGLContext = glue->GetGLContext();
|
||||
data.mStream = mStream.get();
|
||||
data.mTexID = (uint32_t)((uintptr_t)mTarget->GetNativeSurface(NativeSurfaceType::OPENGL_TEXTURE));
|
||||
}
|
||||
} else {
|
||||
data.mDrawTarget = mTarget;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class nsXULElement;
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
@ -596,7 +597,6 @@ protected:
|
|||
return CurrentState().font;
|
||||
}
|
||||
|
||||
#if USE_SKIA_GPU
|
||||
static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
|
||||
static void DemoteOldestContextIfNecessary();
|
||||
|
||||
|
@ -605,7 +605,6 @@ protected:
|
|||
|
||||
// Do not use GL
|
||||
bool mForceSoftware;
|
||||
#endif
|
||||
|
||||
// Member vars
|
||||
int32_t mWidth, mHeight;
|
||||
|
@ -632,6 +631,8 @@ protected:
|
|||
// sErrorTarget.
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
|
||||
|
||||
RefPtr<gfx::SurfaceStream> mStream;
|
||||
|
||||
/**
|
||||
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
|
||||
* Redraw is called, reset to false when Render is called.
|
||||
|
|
21
gfx/2d/2D.h
21
gfx/2d/2D.h
|
@ -971,15 +971,10 @@ public:
|
|||
return mPermitSubpixelAA;
|
||||
}
|
||||
|
||||
virtual GenericRefCountedBase* GetGLContext() const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
virtual void InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
|
||||
GrGLInterface* aGrGLInterface,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
virtual void InitWithGrContext(GrContext* aGrContext,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -1085,13 +1080,9 @@ public:
|
|||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static TemporaryRef<DrawTarget>
|
||||
CreateDrawTargetSkiaWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
|
||||
GrGLInterface* aGrGLInterface,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
static void
|
||||
SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes);
|
||||
CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat);
|
||||
#endif
|
||||
|
||||
static void PurgeAllCaches();
|
||||
|
|
|
@ -79,80 +79,6 @@ public:
|
|||
ExtendMode mExtendMode;
|
||||
};
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
int DrawTargetSkia::sTextureCacheCount = 256;
|
||||
int DrawTargetSkia::sTextureCacheSizeInBytes = 96*1024*1024;
|
||||
|
||||
static std::vector<DrawTargetSkia*>&
|
||||
GLDrawTargets()
|
||||
{
|
||||
static std::vector<DrawTargetSkia*> targets;
|
||||
return targets;
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::RebalanceCacheLimits()
|
||||
{
|
||||
// Divide the global cache limits equally between all currently active GL-backed
|
||||
// Skia DrawTargets.
|
||||
std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
|
||||
uint32_t targetCount = targets.size();
|
||||
if (targetCount == 0)
|
||||
return;
|
||||
|
||||
int individualCacheSize = sTextureCacheSizeInBytes / targetCount;
|
||||
for (uint32_t i = 0; i < targetCount; i++) {
|
||||
targets[i]->SetCacheLimits(sTextureCacheCount, individualCacheSize);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AddGLDrawTarget(DrawTargetSkia* target)
|
||||
{
|
||||
GLDrawTargets().push_back(target);
|
||||
DrawTargetSkia::RebalanceCacheLimits();
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveGLDrawTarget(DrawTargetSkia* target)
|
||||
{
|
||||
std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
|
||||
std::vector<DrawTargetSkia*>::iterator it = std::find(targets.begin(), targets.end(), target);
|
||||
if (it != targets.end()) {
|
||||
targets.erase(it);
|
||||
DrawTargetSkia::RebalanceCacheLimits();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::SetGlobalCacheLimits(int aCount, int aSizeInBytes)
|
||||
{
|
||||
sTextureCacheCount = aCount;
|
||||
sTextureCacheSizeInBytes = aSizeInBytes;
|
||||
|
||||
DrawTargetSkia::RebalanceCacheLimits();
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::PurgeCaches()
|
||||
{
|
||||
if (mGrContext) {
|
||||
mGrContext->freeGpuResources();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
DrawTargetSkia::PurgeAllCaches()
|
||||
{
|
||||
std::vector<DrawTargetSkia*>& targets = GLDrawTargets();
|
||||
uint32_t targetCount = targets.size();
|
||||
for (uint32_t i = 0; i < targetCount; i++) {
|
||||
targets[i]->PurgeCaches();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* When constructing a temporary SkBitmap via GetBitmapForSurface, we may also
|
||||
* have to construct a temporary DataSourceSurface, which must live as long as
|
||||
|
@ -189,15 +115,12 @@ GetBitmapForSurface(SourceSurface* aSurface)
|
|||
}
|
||||
|
||||
DrawTargetSkia::DrawTargetSkia()
|
||||
: mSnapshot(nullptr)
|
||||
: mTexture(0), mSnapshot(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
DrawTargetSkia::~DrawTargetSkia()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
RemoveGLDrawTarget(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
TemporaryRef<SourceSurface>
|
||||
|
@ -770,45 +693,33 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
|
|||
|
||||
#ifdef USE_SKIA_GPU
|
||||
void
|
||||
DrawTargetSkia::InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
|
||||
GrGLInterface* aGrGLInterface,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
mGLContext = aGLContext;
|
||||
mGrContext = aGrContext;
|
||||
|
||||
mSize = aSize;
|
||||
mFormat = aFormat;
|
||||
|
||||
mGrGLInterface = aGrGLInterface;
|
||||
mGrGLInterface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
|
||||
|
||||
GrBackendContext backendContext = reinterpret_cast<GrBackendContext>(aGrGLInterface);
|
||||
SkAutoTUnref<GrContext> gr(GrContext::Create(kOpenGL_GrBackend, backendContext));
|
||||
mGrContext = gr.get();
|
||||
|
||||
GrBackendRenderTargetDesc targetDescriptor;
|
||||
GrTextureDesc targetDescriptor;
|
||||
|
||||
targetDescriptor.fFlags = kRenderTarget_GrTextureFlagBit;
|
||||
targetDescriptor.fWidth = mSize.width;
|
||||
targetDescriptor.fHeight = mSize.height;
|
||||
targetDescriptor.fConfig = GfxFormatToGrConfig(mFormat);
|
||||
targetDescriptor.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||
targetDescriptor.fSampleCnt = 0;
|
||||
targetDescriptor.fRenderTargetHandle = 0; // GLContext always exposes the right framebuffer as id 0
|
||||
|
||||
SkAutoTUnref<GrRenderTarget> target(mGrContext->wrapBackendRenderTarget(targetDescriptor));
|
||||
SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), target.get()));
|
||||
SkAutoTUnref<GrTexture> skiaTexture(mGrContext->createUncachedTexture(targetDescriptor, NULL, 0));
|
||||
|
||||
mTexture = (uint32_t)skiaTexture->getTextureHandle();
|
||||
|
||||
SkAutoTUnref<SkBaseDevice> device(new SkGpuDevice(mGrContext.get(), skiaTexture->asRenderTarget()));
|
||||
SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
|
||||
mCanvas = canvas.get();
|
||||
|
||||
AddGLDrawTarget(this);
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetSkia::SetCacheLimits(int aCount, int aSizeInBytes)
|
||||
{
|
||||
MOZ_ASSERT(mGrContext, "No GrContext!");
|
||||
mGrContext->setTextureCacheLimits(aCount, aSizeInBytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -840,6 +751,17 @@ DrawTargetSkia::SetTransform(const Matrix& aTransform)
|
|||
mTransform = aTransform;
|
||||
}
|
||||
|
||||
void*
|
||||
DrawTargetSkia::GetNativeSurface(NativeSurfaceType aType)
|
||||
{
|
||||
if (aType == NativeSurfaceType::OPENGL_TEXTURE) {
|
||||
return (void*)((uintptr_t)mTexture);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
TemporaryRef<PathBuilder>
|
||||
DrawTargetSkia::CreatePathBuilder(FillRule aFillRule) const
|
||||
{
|
||||
|
|
|
@ -100,23 +100,15 @@ public:
|
|||
virtual TemporaryRef<GradientStops> CreateGradientStops(GradientStop *aStops, uint32_t aNumStops, ExtendMode aExtendMode = ExtendMode::CLAMP) const;
|
||||
virtual TemporaryRef<FilterNode> CreateFilter(FilterType aType);
|
||||
virtual void SetTransform(const Matrix &aTransform);
|
||||
virtual void *GetNativeSurface(NativeSurfaceType aType);
|
||||
|
||||
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
|
||||
void Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
virtual GenericRefCountedBase* GetGLContext() const MOZ_OVERRIDE { return mGLContext; }
|
||||
void InitWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
|
||||
GrGLInterface* aGrGLInterface,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat) MOZ_OVERRIDE;
|
||||
|
||||
void SetCacheLimits(int aCount, int aSizeInBytes);
|
||||
void PurgeCaches();
|
||||
|
||||
static void SetGlobalCacheLimits(int aCount, int aSizeInBytes);
|
||||
static void RebalanceCacheLimits();
|
||||
static void PurgeAllCaches();
|
||||
void InitWithGrContext(GrContext* aGrContext,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat) MOZ_OVERRIDE;
|
||||
#endif
|
||||
|
||||
operator std::string() const {
|
||||
|
@ -134,18 +126,8 @@ private:
|
|||
SkRect SkRectCoveringWholeSurface() const;
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
/*
|
||||
* These members have inter-dependencies, but do not keep each other alive, so
|
||||
* destruction order is very important here: mGrContext uses mGrGLInterface, and
|
||||
* through it, uses mGLContext, so it is important that they be declared in the
|
||||
* present order.
|
||||
*/
|
||||
RefPtr<GenericRefCountedBase> mGLContext;
|
||||
SkRefPtr<GrGLInterface> mGrGLInterface;
|
||||
SkRefPtr<GrContext> mGrContext;
|
||||
|
||||
static int sTextureCacheCount;
|
||||
static int sTextureCacheSizeInBytes;
|
||||
uint32_t mTexture;
|
||||
#endif
|
||||
|
||||
IntSize mSize;
|
||||
|
|
|
@ -586,30 +586,21 @@ Factory::D2DCleanup()
|
|||
|
||||
#ifdef USE_SKIA_GPU
|
||||
TemporaryRef<DrawTarget>
|
||||
Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(GenericRefCountedBase* aGLContext,
|
||||
GrGLInterface* aGrGLInterface,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
Factory::CreateDrawTargetSkiaWithGrContext(GrContext* aGrContext,
|
||||
const IntSize &aSize,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
DrawTargetSkia* newDrawTargetSkia = new DrawTargetSkia();
|
||||
newDrawTargetSkia->InitWithGLContextAndGrGLInterface(aGLContext, aGrGLInterface, aSize, aFormat);
|
||||
newDrawTargetSkia->InitWithGrContext(aGrContext, aSize, aFormat);
|
||||
RefPtr<DrawTarget> newTarget = newDrawTargetSkia;
|
||||
return newTarget;
|
||||
}
|
||||
|
||||
void
|
||||
Factory::SetGlobalSkiaCacheLimits(int aCount, int aSizeInBytes)
|
||||
{
|
||||
DrawTargetSkia::SetGlobalCacheLimits(aCount, aSizeInBytes);
|
||||
}
|
||||
#endif // USE_SKIA_GPU
|
||||
|
||||
void
|
||||
Factory::PurgeAllCaches()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
DrawTargetSkia::PurgeAllCaches();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_FREETYPE
|
||||
|
|
|
@ -96,7 +96,8 @@ MOZ_BEGIN_ENUM_CLASS(NativeSurfaceType, int8_t)
|
|||
CAIRO_SURFACE,
|
||||
CAIRO_CONTEXT,
|
||||
CGCONTEXT,
|
||||
CGCONTEXT_ACCELERATED
|
||||
CGCONTEXT_ACCELERATED,
|
||||
OPENGL_TEXTURE
|
||||
MOZ_END_ENUM_CLASS(NativeSurfaceType)
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(NativeFontType, int8_t)
|
||||
|
|
|
@ -1,8 +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 "skia/GrGLInterface.h"
|
||||
|
||||
GrGLInterface* CreateGrGLInterfaceFromGLContext(mozilla::gl::GLContext* context);
|
|
@ -43,6 +43,7 @@ GLScreenBuffer::Create(GLContext* gl,
|
|||
#ifdef MOZ_WIDGET_GONK
|
||||
/* On B2G, we want a Gralloc factory, and we want one right at the start */
|
||||
if (!factory &&
|
||||
caps.surfaceAllocator &&
|
||||
XRE_GetProcessType() != GeckoProcessType_Default)
|
||||
{
|
||||
factory = new SurfaceFactory_Gralloc(gl, caps);
|
||||
|
@ -70,7 +71,6 @@ GLScreenBuffer::Create(GLContext* gl,
|
|||
|
||||
GLScreenBuffer::~GLScreenBuffer()
|
||||
{
|
||||
delete mStream;
|
||||
delete mDraw;
|
||||
delete mRead;
|
||||
|
||||
|
@ -378,7 +378,6 @@ GLScreenBuffer::Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamTyp
|
|||
SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
|
||||
MOZ_ASSERT(newStream);
|
||||
|
||||
delete mStream;
|
||||
mStream = newStream;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define SCREEN_BUFFER_H_
|
||||
|
||||
#include "SurfaceTypes.h"
|
||||
#include "SurfaceStream.h"
|
||||
#include "GLContextTypes.h"
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
@ -156,7 +157,7 @@ protected:
|
|||
GLContext* const mGL; // Owns us.
|
||||
SurfaceCaps mCaps;
|
||||
SurfaceFactory_GL* mFactory; // Owned by us.
|
||||
SurfaceStream* mStream; // Owned by us.
|
||||
RefPtr<SurfaceStream> mStream;
|
||||
|
||||
DrawBuffer* mDraw; // Owned by us.
|
||||
ReadBuffer* mRead; // Owned by us.
|
||||
|
|
|
@ -283,8 +283,24 @@ SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
|
|||
gl,
|
||||
size,
|
||||
hasAlpha)
|
||||
, mTex(tex)
|
||||
, mTex(tex), mFB(0)
|
||||
{
|
||||
mGL->MakeCurrent();
|
||||
mGL->fGenFramebuffers(1, &mFB);
|
||||
|
||||
ScopedBindFramebuffer autoFB(mGL, mFB);
|
||||
mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
|
||||
LOCAL_GL_COLOR_ATTACHMENT0,
|
||||
LOCAL_GL_TEXTURE_2D,
|
||||
mTex,
|
||||
0);
|
||||
|
||||
GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
||||
mGL->fDeleteFramebuffers(1, &mFB);
|
||||
mFB = 0;
|
||||
}
|
||||
|
||||
mData = Factory::CreateDataSourceSurfaceWithStride(size, format,
|
||||
GetAlignedStride<4>(size.width * BytesPerPixel(format)));
|
||||
}
|
||||
|
@ -294,16 +310,19 @@ SharedSurface_Basic::~SharedSurface_Basic()
|
|||
if (!mGL->MakeCurrent())
|
||||
return;
|
||||
|
||||
if (mFB)
|
||||
mGL->fDeleteFramebuffers(1, &mFB);
|
||||
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
}
|
||||
|
||||
void
|
||||
SharedSurface_Basic::Fence()
|
||||
{
|
||||
MOZ_ASSERT(mData->GetSize() == mGL->OffscreenSize());
|
||||
|
||||
mGL->MakeCurrent();
|
||||
|
||||
ScopedBindFramebuffer autoFB(mGL, mFB);
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
mData->Map(DataSourceSurface::MapType::WRITE, &map);
|
||||
nsRefPtr<gfxImageSurface> wrappedData =
|
||||
|
@ -311,7 +330,7 @@ SharedSurface_Basic::Fence()
|
|||
ThebesIntSize(mData->GetSize()),
|
||||
map.mStride,
|
||||
SurfaceFormatToImageFormat(mData->GetFormat()));
|
||||
ReadScreenIntoImageSurface(mGL, wrappedData);
|
||||
ReadPixelsIntoImageSurface(mGL, wrappedData);
|
||||
mData->Unmap();
|
||||
}
|
||||
|
||||
|
@ -322,15 +341,24 @@ SharedSurface_GLTexture::Create(GLContext* prodGL,
|
|||
GLContext* consGL,
|
||||
const GLFormats& formats,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha)
|
||||
bool hasAlpha,
|
||||
GLuint texture)
|
||||
{
|
||||
MOZ_ASSERT(prodGL);
|
||||
MOZ_ASSERT(!consGL || prodGL->SharesWith(consGL));
|
||||
|
||||
prodGL->MakeCurrent();
|
||||
GLuint tex = CreateTextureForOffscreen(prodGL, formats, size);
|
||||
|
||||
return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex);
|
||||
GLuint tex = texture;
|
||||
|
||||
bool ownsTex = false;
|
||||
|
||||
if (!tex) {
|
||||
tex = CreateTextureForOffscreen(prodGL, formats, size);
|
||||
ownsTex = true;
|
||||
}
|
||||
|
||||
return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex, ownsTex);
|
||||
}
|
||||
|
||||
SharedSurface_GLTexture::~SharedSurface_GLTexture()
|
||||
|
@ -338,7 +366,9 @@ SharedSurface_GLTexture::~SharedSurface_GLTexture()
|
|||
if (!mGL->MakeCurrent())
|
||||
return;
|
||||
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
if (mOwnsTex) {
|
||||
mGL->fDeleteTextures(1, &mTex);
|
||||
}
|
||||
|
||||
if (mSync) {
|
||||
mGL->fDeleteSync(mSync);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef SHARED_SURFACE_GL_H_
|
||||
#define SHARED_SURFACE_GL_H_
|
||||
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SurfaceFactory.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
@ -135,6 +136,8 @@ public:
|
|||
|
||||
protected:
|
||||
const GLuint mTex;
|
||||
GLuint mFB;
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> mData;
|
||||
|
||||
SharedSurface_Basic(GLContext* gl,
|
||||
|
@ -192,7 +195,8 @@ public:
|
|||
GLContext* consGL,
|
||||
const GLFormats& formats,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha);
|
||||
bool hasAlpha,
|
||||
GLuint texture = 0);
|
||||
|
||||
static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
|
||||
MOZ_ASSERT(surf->Type() == SharedSurfaceType::GLTextureShare);
|
||||
|
@ -203,6 +207,7 @@ public:
|
|||
protected:
|
||||
GLContext* mConsGL;
|
||||
const GLuint mTex;
|
||||
const bool mOwnsTex;
|
||||
GLsync mSync;
|
||||
mutable Mutex mMutex;
|
||||
|
||||
|
@ -210,7 +215,8 @@ protected:
|
|||
GLContext* consGL,
|
||||
const gfx::IntSize& size,
|
||||
bool hasAlpha,
|
||||
GLuint tex)
|
||||
GLuint tex,
|
||||
bool ownsTex)
|
||||
: SharedSurface_GL(SharedSurfaceType::GLTextureShare,
|
||||
AttachmentType::GLTexture,
|
||||
prodGL,
|
||||
|
@ -218,6 +224,7 @@ protected:
|
|||
hasAlpha)
|
||||
, mConsGL(consGL)
|
||||
, mTex(tex)
|
||||
, mOwnsTex(ownsTex)
|
||||
, mSync(0)
|
||||
, mMutex("SharedSurface_GLTexture mutex")
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* 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 "skia/GrContext.h"
|
||||
#include "skia/GrGLInterface.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
|
@ -16,9 +17,11 @@
|
|||
#endif
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "SkiaGLGlue.h"
|
||||
|
||||
using mozilla::gl::GLContext;
|
||||
using mozilla::gl::GLFeature;
|
||||
using mozilla::gl::SkiaGLGlue;
|
||||
using mozilla::gfx::DrawTarget;
|
||||
|
||||
static mozilla::ThreadLocal<GLContext*> sGLContext;
|
||||
|
@ -27,8 +30,8 @@ extern "C" {
|
|||
|
||||
void EnsureGLContext(const GrGLInterface* i)
|
||||
{
|
||||
const DrawTarget* drawTarget = reinterpret_cast<const DrawTarget*>(i->fCallbackData);
|
||||
GLContext* gl = static_cast<GLContext*>(drawTarget->GetGLContext());
|
||||
const SkiaGLGlue* contextSkia = reinterpret_cast<const SkiaGLGlue*>(i->fCallbackData);
|
||||
GLContext* gl = contextSkia->GetGLContext();
|
||||
gl->MakeCurrent();
|
||||
|
||||
if (!sGLContext.initialized()) {
|
||||
|
@ -775,7 +778,7 @@ GrGLvoid glVertexPointer_mozilla(GrGLint size, GrGLenum type, GrGLsizei stride,
|
|||
|
||||
} // extern "C"
|
||||
|
||||
GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
||||
{
|
||||
GrGLInterface* i = new GrGLInterface();
|
||||
i->fCallback = EnsureGLContext;
|
||||
|
@ -934,3 +937,14 @@ GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context)
|
|||
|
||||
return i;
|
||||
}
|
||||
|
||||
SkiaGLGlue::SkiaGLGlue(GLContext* context)
|
||||
: mGLContext(context)
|
||||
{
|
||||
SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(mGLContext));
|
||||
i->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
|
||||
mGrGLInterface = i;
|
||||
SkAutoTUnref<GrContext> gr(GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)mGrGLInterface.get()));
|
||||
|
||||
mGrContext = gr;
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- 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 "mozilla/RefPtr.h"
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "skia/GrGLInterface.h"
|
||||
#include "skia/GrContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class SkiaGLGlue : public GenericAtomicRefCounted
|
||||
{
|
||||
public:
|
||||
SkiaGLGlue(GLContext* context);
|
||||
GLContext* GetGLContext() const { return mGLContext.get(); }
|
||||
GrContext* GetGrContext() const { return mGrContext.get(); }
|
||||
|
||||
protected:
|
||||
virtual ~SkiaGLGlue() {
|
||||
/*
|
||||
* These members have inter-dependencies, but do not keep each other alive, so
|
||||
* destruction order is very important here: mGrContext uses mGrGLInterface, and
|
||||
* through it, uses mGLContext
|
||||
*/
|
||||
mGrContext = nullptr;
|
||||
mGrGLInterface = nullptr;
|
||||
mGLContext = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<GLContext> mGLContext;
|
||||
SkRefPtr<GrGLInterface> mGrGLInterface;
|
||||
SkRefPtr<GrContext> mGrContext;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
class GrContext;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLContext;
|
||||
|
||||
class SkiaGLGlue : public GenericAtomicRefCounted
|
||||
{
|
||||
public:
|
||||
SkiaGLGlue(GLContext* context);
|
||||
GLContext* GetGLContext() const { return nullptr; }
|
||||
GrContext* GetGrContext() const { return nullptr; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "gfxPoint.h"
|
||||
#include "SharedSurface.h"
|
||||
#include "SharedSurfaceGL.h"
|
||||
#include "SurfaceFactory.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
|
@ -53,6 +54,22 @@ SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glC
|
|||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory)
|
||||
{
|
||||
if (!mProducer) {
|
||||
New(factory, src->Size(), mProducer);
|
||||
if (!mProducer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(src->Size() == mProducer->Size(), "Size mismatch");
|
||||
|
||||
SharedSurface::Copy(src, mProducer, factory);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size,
|
||||
SharedSurface*& surf)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/GenericRefCounted.h"
|
||||
#include "SurfaceTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -24,7 +25,7 @@ class SharedSurface;
|
|||
class SurfaceFactory;
|
||||
|
||||
// Owned by: ScreenBuffer
|
||||
class SurfaceStream
|
||||
class SurfaceStream : public GenericAtomicRefCounted
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
|
@ -50,6 +51,8 @@ public:
|
|||
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.
|
||||
|
@ -121,6 +124,8 @@ public:
|
|||
|
||||
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.
|
||||
|
@ -189,6 +194,7 @@ protected:
|
|||
public:
|
||||
SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
|
||||
virtual ~SurfaceStream_TripleBuffer();
|
||||
virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory);
|
||||
|
||||
private:
|
||||
// Common constructor code.
|
||||
|
|
|
@ -75,9 +75,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'SharedSurfaceANGLE.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_ENABLE_SKIA_GPU']:
|
||||
EXPORTS += ['GLContextSkia.h']
|
||||
EXPORTS += ['SkiaGLGlue.h']
|
||||
UNIFIED_SOURCES += [
|
||||
'GLContextSkia.cpp',
|
||||
'SkiaGLGlue.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace layers {
|
|||
|
||||
CopyableCanvasLayer::CopyableCanvasLayer(LayerManager* aLayerManager, void *aImplData) :
|
||||
CanvasLayer(aLayerManager, aImplData)
|
||||
, mStream(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CopyableCanvasLayer);
|
||||
}
|
||||
|
@ -48,6 +49,7 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
|||
|
||||
if (aData.mGLContext) {
|
||||
mGLContext = aData.mGLContext;
|
||||
mStream = aData.mStream;
|
||||
mIsGLAlphaPremult = aData.mIsGLAlphaPremult;
|
||||
mNeedsYFlip = true;
|
||||
MOZ_ASSERT(mGLContext->IsOffscreen(), "canvas gl context isn't offscreen");
|
||||
|
@ -70,7 +72,7 @@ CopyableCanvasLayer::Initialize(const Data& aData)
|
|||
bool
|
||||
CopyableCanvasLayer::IsDataValid(const Data& aData)
|
||||
{
|
||||
return mGLContext == aData.mGLContext;
|
||||
return mGLContext == aData.mGLContext && mStream == aData.mStream;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -22,6 +22,13 @@
|
|||
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gfx {
|
||||
class SurfaceStream;
|
||||
class SharedSurface;
|
||||
class SurfaceFactory;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class CanvasClientWebGL;
|
||||
|
@ -54,6 +61,8 @@ protected:
|
|||
nsRefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
mozilla::RefPtr<mozilla::gfx::DrawTarget> mDrawTarget;
|
||||
|
||||
RefPtr<gfx::SurfaceStream> mStream;
|
||||
|
||||
uint32_t mCanvasFramebuffer;
|
||||
|
||||
bool mIsGLAlphaPremult;
|
||||
|
|
|
@ -63,6 +63,7 @@ class GLContext;
|
|||
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
class SurfaceStream;
|
||||
}
|
||||
|
||||
namespace css {
|
||||
|
@ -1796,6 +1797,8 @@ public:
|
|||
Data()
|
||||
: mDrawTarget(nullptr)
|
||||
, mGLContext(nullptr)
|
||||
, mStream(nullptr)
|
||||
, mTexID(0)
|
||||
, mSize(0,0)
|
||||
, mIsGLAlphaPremult(false)
|
||||
{ }
|
||||
|
@ -1804,6 +1807,12 @@ public:
|
|||
mozilla::gfx::DrawTarget *mDrawTarget; // a DrawTarget for the canvas contents
|
||||
mozilla::gl::GLContext* mGLContext; // or this, for GL.
|
||||
|
||||
// Canvas/SkiaGL uses this
|
||||
mozilla::gfx::SurfaceStream* mStream;
|
||||
|
||||
// ID of the texture backing the canvas layer (defaults to 0)
|
||||
uint32_t mTexID;
|
||||
|
||||
// The size of the canvas content
|
||||
nsIntSize mSize;
|
||||
|
||||
|
|
|
@ -116,7 +116,18 @@ void
|
|||
CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
|
||||
{
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
SurfaceStream* stream = screen->Stream();
|
||||
SurfaceStream* stream = nullptr;
|
||||
|
||||
if (aLayer->mStream) {
|
||||
stream = aLayer->mStream;
|
||||
|
||||
// Copy our current surface to the current producer surface in our stream, then
|
||||
// call SwapProducer to make a new buffer ready.
|
||||
stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
|
||||
stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
|
||||
} else {
|
||||
stream = screen->Stream();
|
||||
}
|
||||
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
bool bufferCreated = false;
|
||||
|
@ -255,7 +266,15 @@ DeprecatedCanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLaye
|
|||
mDeprecatedTextureClient->EnsureAllocated(aSize, gfxContentType::COLOR);
|
||||
|
||||
GLScreenBuffer* screen = aLayer->mGLContext->Screen();
|
||||
SurfaceStream* stream = screen->Stream();
|
||||
SurfaceStream* stream = nullptr;
|
||||
|
||||
if (aLayer->mStream) {
|
||||
stream = aLayer->mStream;
|
||||
stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
|
||||
stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
|
||||
} else {
|
||||
stream = screen->Stream();
|
||||
}
|
||||
|
||||
bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
if (isCrossProcess) {
|
||||
|
|
|
@ -33,6 +33,18 @@ using namespace mozilla::gl;
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
ClientCanvasLayer::~ClientCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientCanvasLayer);
|
||||
if (mCanvasClient) {
|
||||
mCanvasClient->OnDetach();
|
||||
mCanvasClient = nullptr;
|
||||
}
|
||||
if (mTextureSurface) {
|
||||
delete mTextureSurface;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientCanvasLayer::Initialize(const Data& aData)
|
||||
{
|
||||
|
@ -42,6 +54,13 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
|
||||
if (mGLContext) {
|
||||
GLScreenBuffer* screen = mGLContext->Screen();
|
||||
|
||||
SurfaceCaps caps = screen->Caps();
|
||||
if (mStream) {
|
||||
// The screen caps are irrelevant if we're using a separate stream
|
||||
caps = GetContentFlags() & CONTENT_OPAQUE ? SurfaceCaps::ForRGB() : SurfaceCaps::ForRGBA();
|
||||
}
|
||||
|
||||
SurfaceStreamType streamType =
|
||||
SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
|
||||
screen->PreserveBuffer());
|
||||
|
@ -53,11 +72,11 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
|
||||
if (!isCrossProcess) {
|
||||
// [Basic/OGL Layers, OMTC] WebGL layer init.
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, screen->Caps());
|
||||
factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
|
||||
} else {
|
||||
// [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
factory = new SurfaceFactory_Gralloc(mGLContext, screen->Caps(), ClientManager()->AsShadowForwarder());
|
||||
factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder());
|
||||
#else
|
||||
// we could do readback here maybe
|
||||
NS_NOTREACHED("isCrossProcess but not on native B2G!");
|
||||
|
@ -67,15 +86,35 @@ ClientCanvasLayer::Initialize(const Data& aData)
|
|||
// [Basic Layers, OMTC] WebGL layer init.
|
||||
// Well, this *should* work...
|
||||
#ifdef XP_MACOSX
|
||||
factory = new SurfaceFactory_IOSurface(mGLContext, screen->Caps());
|
||||
factory = new SurfaceFactory_IOSurface(mGLContext, caps);
|
||||
#else
|
||||
factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, screen->Caps());
|
||||
factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (factory) {
|
||||
if (mStream) {
|
||||
// We're using a stream other than the one in the default screen
|
||||
mFactory = factory;
|
||||
if (!mFactory) {
|
||||
// Absolutely must have a factory here, so create a basic one
|
||||
mFactory = new 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, size);
|
||||
if (!producer) {
|
||||
// Fallback to basic factory
|
||||
delete mFactory;
|
||||
mFactory = new SurfaceFactory_Basic(mGLContext, caps);
|
||||
producer = mStream->SwapProducer(mFactory, size);
|
||||
MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory");
|
||||
}
|
||||
} else if (factory) {
|
||||
screen->Morph(factory, streamType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,17 +33,12 @@ public:
|
|||
ClientCanvasLayer(ClientLayerManager* aLayerManager) :
|
||||
CopyableCanvasLayer(aLayerManager,
|
||||
static_cast<ClientLayer*>(MOZ_THIS_IN_INITIALIZER_LIST()))
|
||||
, mTextureSurface(nullptr)
|
||||
, mFactory(nullptr)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientCanvasLayer);
|
||||
}
|
||||
virtual ~ClientCanvasLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ClientCanvasLayer);
|
||||
if (mCanvasClient) {
|
||||
mCanvasClient->OnDetach();
|
||||
mCanvasClient = nullptr;
|
||||
}
|
||||
}
|
||||
virtual ~ClientCanvasLayer();
|
||||
|
||||
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
|
||||
{
|
||||
|
@ -97,6 +92,9 @@ protected:
|
|||
|
||||
RefPtr<CanvasClient> mCanvasClient;
|
||||
|
||||
gfx::SharedSurface* mTextureSurface;
|
||||
gfx::SurfaceFactory* mFactory;
|
||||
|
||||
friend class DeprecatedCanvasClient2D;
|
||||
friend class CanvasClient2D;
|
||||
friend class DeprecatedCanvasClientSurfaceStream;
|
||||
|
|
|
@ -86,7 +86,6 @@ SharedTextureClientOGL::IsAllocated() const
|
|||
|
||||
StreamTextureClientOGL::StreamTextureClientOGL(TextureFlags aFlags)
|
||||
: TextureClient(aFlags)
|
||||
, mStream(0)
|
||||
, mIsLocked(false)
|
||||
{
|
||||
}
|
||||
|
@ -131,6 +130,7 @@ StreamTextureClientOGL::InitWith(gfx::SurfaceStream* aStream)
|
|||
{
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mStream = aStream;
|
||||
mGL = mStream->GLContext();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -97,8 +97,9 @@ public:
|
|||
virtual gfx::IntSize GetSize() const { return gfx::IntSize(); }
|
||||
|
||||
protected:
|
||||
gfx::SurfaceStream* mStream;
|
||||
bool mIsLocked;
|
||||
RefPtr<gfx::SurfaceStream> mStream;
|
||||
RefPtr<gl::GLContext> mGL;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
#ifdef USE_SKIA
|
||||
#include "mozilla/Hal.h"
|
||||
#include "skia/SkGraphics.h"
|
||||
|
||||
#include "SkiaGLGlue.h"
|
||||
|
||||
#endif
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -202,6 +205,8 @@ MemoryPressureObserver::Observe(nsISupports *aSubject,
|
|||
{
|
||||
NS_ASSERTION(strcmp(aTopic, "memory-pressure") == 0, "unexpected event topic");
|
||||
Factory::PurgeAllCaches();
|
||||
|
||||
gfxPlatform::GetPlatform()->PurgeSkiaCache();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -266,6 +271,8 @@ gfxPlatform::gfxPlatform()
|
|||
mLayersUseDeprecated = false;
|
||||
#endif
|
||||
|
||||
mSkiaGlue = nullptr;
|
||||
|
||||
uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
|
||||
uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
|
||||
InitBackendPrefs(canvasMask, BackendType::CAIRO,
|
||||
|
@ -422,10 +429,6 @@ gfxPlatform::Init()
|
|||
|
||||
CreateCMSOutputProfile();
|
||||
|
||||
#ifdef USE_SKIA
|
||||
gPlatform->InitializeSkiaCaches();
|
||||
#endif
|
||||
|
||||
// Listen to memory pressure event so we can purge DrawTarget caches
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
|
@ -825,9 +828,8 @@ gfxPlatform::UseAcceleratedSkiaCanvas()
|
|||
}
|
||||
|
||||
void
|
||||
gfxPlatform::InitializeSkiaCaches()
|
||||
gfxPlatform::InitializeSkiaCacheLimits()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (UseAcceleratedSkiaCanvas()) {
|
||||
bool usingDynamicCache = gfxPrefs::CanvasSkiaGLDynamicCache();
|
||||
int cacheItemLimit = gfxPrefs::CanvasSkiaGLCacheItems();
|
||||
|
@ -847,12 +849,47 @@ gfxPlatform::InitializeSkiaCaches()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef DEBUG
|
||||
printf_stderr("Determined SkiaGL cache limits: Size %i, Items: %i\n", cacheSizeLimit, cacheItemLimit);
|
||||
#endif
|
||||
|
||||
mSkiaGlue->GetGrContext()->setTextureCacheLimits(cacheItemLimit, cacheSizeLimit);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::gl::SkiaGLGlue*
|
||||
gfxPlatform::GetSkiaGLGlue()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (!mSkiaGlue) {
|
||||
/* Dummy context. We always draw into a FBO.
|
||||
*
|
||||
* FIXME: This should be stored in TLS or something, since there needs to be one for each thread using it. As it
|
||||
* stands, this only works on the main thread.
|
||||
*/
|
||||
mozilla::gfx::SurfaceCaps caps = mozilla::gfx::SurfaceCaps::ForRGBA();
|
||||
nsRefPtr<mozilla::gl::GLContext> glContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(16, 16), caps);
|
||||
if (!glContext) {
|
||||
printf_stderr("Failed to create GLContext for SkiaGL!\n");
|
||||
return nullptr;
|
||||
}
|
||||
mSkiaGlue = new mozilla::gl::SkiaGLGlue(glContext);
|
||||
MOZ_ASSERT(mSkiaGlue->GetGrContext(), "No GrContext");
|
||||
InitializeSkiaCacheLimits();
|
||||
}
|
||||
#endif
|
||||
|
||||
Factory::SetGlobalSkiaCacheLimits(cacheItemLimit, cacheSizeLimit);
|
||||
}
|
||||
return mSkiaGlue;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPlatform::PurgeSkiaCache()
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (!mSkiaGlue)
|
||||
return;
|
||||
|
||||
mSkiaGlue->GetGrContext()->freeGpuResources();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct gfxRGBA;
|
|||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
class SkiaGLGlue;
|
||||
}
|
||||
namespace gfx {
|
||||
class DrawTarget;
|
||||
|
@ -283,8 +284,7 @@ public:
|
|||
}
|
||||
|
||||
virtual bool UseAcceleratedSkiaCanvas();
|
||||
|
||||
virtual void InitializeSkiaCaches();
|
||||
virtual void InitializeSkiaCacheLimits();
|
||||
|
||||
void GetAzureBackendInfo(mozilla::widget::InfoObject &aObj) {
|
||||
aObj.DefineProperty("AzureCanvasBackend", GetBackendName(mPreferredCanvasBackend));
|
||||
|
@ -598,6 +598,9 @@ public:
|
|||
bool PreferMemoryOverShmem() const;
|
||||
bool UseDeprecatedTextures() const { return mLayersUseDeprecated; }
|
||||
|
||||
mozilla::gl::SkiaGLGlue* GetSkiaGLGlue();
|
||||
void PurgeSkiaCache();
|
||||
|
||||
protected:
|
||||
gfxPlatform();
|
||||
virtual ~gfxPlatform();
|
||||
|
@ -711,6 +714,7 @@ private:
|
|||
mozilla::RefPtr<mozilla::gfx::DrawEventRecorder> mRecorder;
|
||||
bool mLayersPreferMemoryOverShmem;
|
||||
bool mLayersUseDeprecated;
|
||||
mozilla::RefPtr<mozilla::gl::SkiaGLGlue> mSkiaGlue;
|
||||
};
|
||||
|
||||
#endif /* GFX_PLATFORM_H */
|
||||
|
|
Загрузка…
Ссылка в новой задаче