Dynamically allocate the GrDrawContexts

This CL moves the allocation and storage of the GrTextContexts into the DrawingManager. The GrDrawContexts now just get their GrTextContext from the DrawingManager.

Review URL: https://codereview.chromium.org/1375153007
This commit is contained in:
robertphillips 2015-10-06 07:38:23 -07:00 committed by Commit bot
parent b0cd8b7146
commit 2d70dcbe5c
5 changed files with 80 additions and 56 deletions

View File

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

View File

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

View File

@ -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() {
}
}
GrTextContext* GrContext::DrawingMgr::textContext(const SkSurfaceProps& props,
GrRenderTarget* rt) {
if (this->abandoned()) {
return nullptr;
}
SkASSERT(props.pixelGeometry() < kNumPixelGeometries);
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;
}
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);
}
// For now, everyone gets a faux creation ref
return SkRef(fDrawContext[props.pixelGeometry()][props.isUseDeviceIndependentFonts()]);
return new GrDrawContext(fContext, fDrawTarget, surfaceProps);
}
////////////////////////////////////////////////////////////////////////////////

View File

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

View File

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