diff options
-rw-r--r-- | include/gpu/GrContext.h | 23 | ||||
-rw-r--r-- | include/gpu/GrDrawContext.h | 6 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 55 | ||||
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 44 | ||||
-rw-r--r-- | src/gpu/GrTextContext.cpp | 4 |
5 files changed, 78 insertions, 54 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 59ce867efd..51879e0626 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -183,6 +183,10 @@ public: return fDrawingMgr.drawContext(surfaceProps); } + GrTextContext* textContext(const SkSurfaceProps& surfaceProps, GrRenderTarget* rt) { + return fDrawingMgr.textContext(surfaceProps, rt); + } + /////////////////////////////////////////////////////////////////////////// // Misc. @@ -410,17 +414,19 @@ private: GrContext(); // init must be called after the constructor. bool init(GrBackend, GrBackendContext, const GrContextOptions& options); - // Currently the DrawingMgr stores a separate GrDrawContext for each + // Currently the DrawingMgr creates a separate GrTextContext for each // combination of text drawing options (pixel geometry x DFT use) - // and hands the appropriate one back given the user's request. - // All of the GrDrawContexts still land in the same GrDrawTarget! + // and hands the appropriate one back given the DrawContext's request. + // + // It allocates a new GrDrawContext for each GrRenderTarget + // but all of them still land in the same GrDrawTarget! // // In the future this class will allocate a new GrDrawContext for // each GrRenderTarget/GrDrawTarget and manage the DAG. class DrawingMgr { public: - DrawingMgr() : fDrawTarget(NULL) { - sk_bzero(fDrawContext, sizeof(fDrawContext)); + DrawingMgr() : fDrawTarget(nullptr), fNVPRTextContext(nullptr) { + sk_bzero(fTextContexts, sizeof(fTextContexts)); } ~DrawingMgr(); @@ -433,10 +439,12 @@ private: void reset(); void flush(); - // Callers should take a ref if they rely on the GrDrawContext sticking around. + // Callers assume the creation ref of the drawContext! // NULL will be returned if the context has been abandoned. GrDrawContext* drawContext(const SkSurfaceProps* surfaceProps); + GrTextContext* textContext(const SkSurfaceProps& props, GrRenderTarget* rt); + private: void cleanup(); @@ -448,7 +456,8 @@ private: GrContext* fContext; GrDrawTarget* fDrawTarget; - GrDrawContext* fDrawContext[kNumPixelGeometries][kNumDFTOptions]; + GrTextContext* fNVPRTextContext; + GrTextContext* fTextContexts[kNumPixelGeometries][kNumDFTOptions]; }; DrawingMgr fDrawingMgr; diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h index 97cb72a7f2..9365021dfa 100644 --- a/include/gpu/GrDrawContext.h +++ b/include/gpu/GrDrawContext.h @@ -263,9 +263,7 @@ private: friend class GrAtlasTextContext; // for access to drawBatch friend class GrContext; // for ctor - GrDrawContext(GrContext*, GrDrawTarget*, const SkSurfaceProps&); - - GrTextContext* createTextContext(GrRenderTarget*, const SkSurfaceProps&); + GrDrawContext(GrContext*, GrDrawTarget*, const SkSurfaceProps* surfaceProps); // Checks if the context has been abandoned and if the rendertarget is owned by this context bool prepareToDraw(GrRenderTarget* rt); @@ -284,7 +282,7 @@ private: GrContext* fContext; // owning context -> no ref GrDrawTarget* fDrawTarget; - GrTextContext* fTextContext; // lazily created + GrTextContext* fTextContext; // lazily gotten from GrContext::DrawingMgr SkSurfaceProps fSurfaceProps; }; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 065d61bb95..b1959bb9fd 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -28,6 +28,7 @@ #include "GrResourceCache.h" #include "GrResourceProvider.h" #include "GrSoftwarePathRenderer.h" +#include "GrStencilAndCoverTextContext.h" #include "GrStrokeInfo.h" #include "GrSurfacePriv.h" #include "GrTextBlobCache.h" @@ -44,6 +45,7 @@ #include "SkTLS.h" #include "SkTraceEvent.h" + #include "batches/GrBatch.h" #include "effects/GrConfigConversionEffect.h" @@ -65,9 +67,13 @@ void GrContext::DrawingMgr::init(GrContext* context) { void GrContext::DrawingMgr::cleanup() { SkSafeSetNull(fDrawTarget); + delete fNVPRTextContext; + fNVPRTextContext = nullptr; for (int i = 0; i < kNumPixelGeometries; ++i) { - SkSafeSetNull(fDrawContext[i][0]); - SkSafeSetNull(fDrawContext[i][1]); + delete fTextContexts[i][0]; + fTextContexts[i][0] = nullptr; + delete fTextContexts[i][1]; + fTextContexts[i][1] = nullptr; } } @@ -76,15 +82,7 @@ GrContext::DrawingMgr::~DrawingMgr() { } void GrContext::DrawingMgr::abandon() { - SkSafeSetNull(fDrawTarget); - for (int i = 0; i < kNumPixelGeometries; ++i) { - for (int j = 0; j < kNumDFTOptions; ++j) { - if (fDrawContext[i][j]) { - SkSafeSetNull(fDrawContext[i][j]->fDrawTarget); - SkSafeSetNull(fDrawContext[i][j]); - } - } - } + this->cleanup(); } void GrContext::DrawingMgr::reset() { @@ -99,21 +97,40 @@ void GrContext::DrawingMgr::flush() { } } -GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) { +GrTextContext* GrContext::DrawingMgr::textContext(const SkSurfaceProps& props, + GrRenderTarget* rt) { if (this->abandoned()) { return nullptr; } - const SkSurfaceProps props(SkSurfacePropsCopyOrDefault(surfaceProps)); - SkASSERT(props.pixelGeometry() < kNumPixelGeometries); - if (!fDrawContext[props.pixelGeometry()][props.isUseDeviceIndependentFonts()]) { - fDrawContext[props.pixelGeometry()][props.isUseDeviceIndependentFonts()] = - new GrDrawContext(fContext, fDrawTarget, props); + bool useDIF = props.isUseDeviceIndependentFonts(); + + if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() && + rt->isStencilBufferMultisampled()) { + GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt); + if (sb) { + if (!fNVPRTextContext) { + fNVPRTextContext = GrStencilAndCoverTextContext::Create(fContext, props); + } + + return fNVPRTextContext; + } + } + + if (!fTextContexts[props.pixelGeometry()][useDIF]) { + fTextContexts[props.pixelGeometry()][useDIF] = GrAtlasTextContext::Create(fContext, props); + } + + return fTextContexts[props.pixelGeometry()][useDIF]; +} + +GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) { + if (this->abandoned()) { + return nullptr; } - // For now, everyone gets a faux creation ref - return SkRef(fDrawContext[props.pixelGeometry()][props.isUseDeviceIndependentFonts()]); + return new GrDrawContext(fContext, fDrawTarget, surfaceProps); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 0a63eb8ebf..7e1e66fb55 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -16,6 +16,7 @@ #include "GrRenderTargetPriv.h" #include "GrResourceProvider.h" #include "GrStencilAndCoverTextContext.h" +#include "SkSurfacePriv.h" #include "batches/GrBatch.h" #include "batches/GrDrawAtlasBatch.h" @@ -23,9 +24,9 @@ #include "batches/GrRectBatchFactory.h" #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == fContext) -#define RETURN_IF_ABANDONED if (!fDrawTarget) { return; } -#define RETURN_FALSE_IF_ABANDONED if (!fDrawTarget) { return false; } -#define RETURN_NULL_IF_ABANDONED if (!fDrawTarget) { return nullptr; } +#define RETURN_IF_ABANDONED if (fContext->abandoned()) { return; } +#define RETURN_FALSE_IF_ABANDONED if (fContext->abandoned()) { return false; } +#define RETURN_NULL_IF_ABANDONED if (fContext->abandoned()) { return nullptr; } class AutoCheckFlush { public: @@ -38,20 +39,21 @@ private: GrDrawContext::GrDrawContext(GrContext* context, GrDrawTarget* drawTarget, - const SkSurfaceProps& surfaceProps) + const SkSurfaceProps* surfaceProps) : fContext(context) , fDrawTarget(SkRef(drawTarget)) , fTextContext(nullptr) - , fSurfaceProps(surfaceProps) { + , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps)) { } GrDrawContext::~GrDrawContext() { SkSafeUnref(fDrawTarget); - delete fTextContext; } void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) { + RETURN_IF_ABANDONED + if (!this->prepareToDraw(dst)) { return; } @@ -59,28 +61,16 @@ void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src, fDrawTarget->copySurface(dst, src, srcRect, dstPoint); } -GrTextContext* GrDrawContext::createTextContext(GrRenderTarget* renderTarget, - const SkSurfaceProps& surfaceProps) { - if (fContext->caps()->shaderCaps()->pathRenderingSupport() && - renderTarget->isStencilBufferMultisampled() && - fSurfaceProps.isUseDeviceIndependentFonts()) { - GrStencilAttachment* sb = - fContext->resourceProvider()->attachStencilAttachment(renderTarget); - if (sb) { - return GrStencilAndCoverTextContext::Create(fContext, surfaceProps); - } - } - - return GrAtlasTextContext::Create(fContext, surfaceProps); -} void GrDrawContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint, const SkPaint& skPaint, const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkIRect& clipBounds) { + RETURN_IF_ABANDONED + if (!fTextContext) { - fTextContext = this->createTextContext(rt, fSurfaceProps); + fTextContext = fContext->textContext(fSurfaceProps, rt); } fTextContext->drawText(this, rt, clip, grPaint, skPaint, viewMatrix, @@ -93,8 +83,10 @@ void GrDrawContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const Gr const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset, const SkIRect& clipBounds) { + RETURN_IF_ABANDONED + if (!fTextContext) { - fTextContext = this->createTextContext(rt, fSurfaceProps); + fTextContext = fContext->textContext(fSurfaceProps, rt); } fTextContext->drawPosText(this, rt, clip, grPaint, skPaint, viewMatrix, text, byteLength, @@ -105,8 +97,10 @@ void GrDrawContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, const S const SkMatrix& viewMatrix, const SkTextBlob* blob, SkScalar x, SkScalar y, SkDrawFilter* filter, const SkIRect& clipBounds) { + RETURN_IF_ABANDONED + if (!fTextContext) { - fTextContext = this->createTextContext(rt, fSurfaceProps); + fTextContext = fContext->textContext(fSurfaceProps, rt); } fTextContext->drawTextBlob(this, rt, @@ -119,6 +113,8 @@ void GrDrawContext::drawPathsFromRange(const GrPipelineBuilder* pipelineBuilder, GrColor color, GrPathRangeDraw* draw, int /*GrPathRendering::FillType*/ fill) { + RETURN_IF_ABANDONED + fDrawTarget->drawPathsFromRange(*pipelineBuilder, viewMatrix, localMatrix, color, draw, (GrPathRendering::FillType) fill); } @@ -761,5 +757,7 @@ bool GrDrawContext::prepareToDraw(GrRenderTarget* rt) { } void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* batch) { + RETURN_IF_ABANDONED + fDrawTarget->drawBatch(*pipelineBuilder, batch); } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 1041b880f1..a2e245d7e5 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -27,7 +27,9 @@ GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr , fSurfaceProps(surfaceProps) { } -GrTextContext::~GrTextContext() { delete fFallbackTextContext; } +GrTextContext::~GrTextContext() { + delete fFallbackTextContext; +} void GrTextContext::drawText(GrDrawContext* dc, GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, |