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:
James Willcox 2014-03-05 15:49:37 -06:00
Родитель 1fd761ef37
Коммит dfee0058ef
27 изменённых файлов: 400 добавлений и 296 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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;
}

64
gfx/gl/SkiaGLGlue.h Executable file
Просмотреть файл

@ -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,15 +33,34 @@ 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)
{
CopyableCanvasLayer::Initialize(aData);
mCanvasClient = nullptr;
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 */