Index: src/gpu/GrDrawContext.cpp |
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrDrawContext.cpp |
old mode 100755 |
new mode 100644 |
similarity index 50% |
copy from src/gpu/GrContext.cpp |
copy to src/gpu/GrDrawContext.cpp |
index 3ed0b6baa26fc37c9483c44b0fa9b30aee85dd7b..3fe3f867199f8ed990cc670288d9fb5b70cf0375 |
--- a/src/gpu/GrContext.cpp |
+++ b/src/gpu/GrDrawContext.cpp |
@@ -1,306 +1,96 @@ |
/* |
- * Copyright 2011 Google Inc. |
+ * Copyright 2015 Google Inc. |
* |
* Use of this source code is governed by a BSD-style license that can be |
* found in the LICENSE file. |
*/ |
-#include "GrContext.h" |
- |
#include "GrAARectRenderer.h" |
-#include "GrAtlasTextContext.h" |
#include "GrBatch.h" |
-#include "GrBatchFontCache.h" |
-#include "GrBatchTarget.h" |
#include "GrBatchTest.h" |
-#include "GrCaps.h" |
-#include "GrContextOptions.h" |
#include "GrDefaultGeoProcFactory.h" |
-#include "GrGpuResource.h" |
-#include "GrGpuResourcePriv.h" |
-#include "GrGpu.h" |
-#include "GrImmediateDrawTarget.h" |
-#include "GrIndexBuffer.h" |
-#include "GrInOrderDrawBuffer.h" |
-#include "GrLayerCache.h" |
+#include "GrDrawContext.h" |
#include "GrOvalRenderer.h" |
#include "GrPathRenderer.h" |
-#include "GrPathUtils.h" |
-#include "GrRenderTargetPriv.h" |
-#include "GrResourceCache.h" |
-#include "GrResourceProvider.h" |
-#include "GrSoftwarePathRenderer.h" |
-#include "GrStencilAndCoverTextContext.h" |
-#include "GrStrokeInfo.h" |
-#include "GrSurfacePriv.h" |
-#include "GrTextBlobCache.h" |
-#include "GrTexturePriv.h" |
-#include "GrTraceMarker.h" |
-#include "GrTracing.h" |
-#include "GrVertices.h" |
-#include "SkDashPathPriv.h" |
-#include "SkConfig8888.h" |
-#include "SkGr.h" |
-#include "SkRRect.h" |
-#include "SkStrokeRec.h" |
-#include "SkTLazy.h" |
-#include "SkTLS.h" |
-#include "SkTraceEvent.h" |
- |
-#include "effects/GrConfigConversionEffect.h" |
-#include "effects/GrDashingEffect.h" |
-#include "effects/GrSingleTextureEffect.h" |
- |
-#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this) |
-#define RETURN_IF_ABANDONED if (!fDrawBuffer) { return; } |
-#define RETURN_FALSE_IF_ABANDONED if (!fDrawBuffer) { return false; } |
-#define RETURN_NULL_IF_ABANDONED if (!fDrawBuffer) { return NULL; } |
- |
-class GrContext::AutoCheckFlush { |
+ |
+#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 NULL; } |
+ |
+class AutoCheckFlush { |
public: |
AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); } |
- |
- ~AutoCheckFlush() { |
- if (fContext->fFlushToReduceCacheSize) { |
- fContext->flush(); |
- } |
- } |
+ ~AutoCheckFlush() { fContext->flushIfNecessary(); } |
private: |
GrContext* fContext; |
}; |
-GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) { |
- GrContextOptions defaultOptions; |
- return Create(backend, backendContext, defaultOptions); |
-} |
- |
-GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext, |
- const GrContextOptions& options) { |
- GrContext* context = SkNEW(GrContext); |
- |
- if (context->init(backend, backendContext, options)) { |
- return context; |
- } else { |
- context->unref(); |
- return NULL; |
- } |
+GrDrawContext::GrDrawContext(GrContext* context, GrDrawTarget* drawTarget) |
+ : fContext(context) |
+ , fDrawTarget(SkRef(drawTarget)) { |
} |
-static int32_t gNextID = 1; |
-static int32_t next_id() { |
- int32_t id; |
- do { |
- id = sk_atomic_inc(&gNextID); |
- } while (id == SK_InvalidGenID); |
- return id; |
-} |
- |
-GrContext::GrContext() : fUniqueID(next_id()) { |
- fGpu = NULL; |
- fResourceCache = NULL; |
- fResourceProvider = NULL; |
- fPathRendererChain = NULL; |
- fSoftwarePathRenderer = NULL; |
- fBatchFontCache = NULL; |
- fDrawBuffer = NULL; |
- fFlushToReduceCacheSize = false; |
- fAARectRenderer = NULL; |
- fOvalRenderer = NULL; |
- fMaxTextureSizeOverride = 1 << 20; |
-} |
- |
-bool GrContext::init(GrBackend backend, GrBackendContext backendContext, |
- const GrContextOptions& options) { |
- SkASSERT(NULL == fGpu); |
- |
- fGpu = GrGpu::Create(backend, backendContext, options, this); |
- if (NULL == fGpu) { |
- return false; |
- } |
- this->initCommon(); |
- return true; |
-} |
- |
-void GrContext::initCommon() { |
- fResourceCache = SkNEW(GrResourceCache); |
- fResourceCache->setOverBudgetCallback(OverBudgetCB, this); |
- fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache)); |
- |
- fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); |
- |
- fAARectRenderer = SkNEW(GrAARectRenderer); |
- fOvalRenderer = SkNEW(GrOvalRenderer); |
- |
- fDidTestPMConversions = false; |
- |
-#ifdef IMMEDIATE_MODE |
- fDrawBuffer = SkNEW_ARGS(GrImmediateDrawTarget, (this)); |
-#else |
- fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (this)); |
-#endif |
- |
- // GrBatchFontCache will eventually replace GrFontCache |
- fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this)); |
- |
- fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this))); |
-} |
- |
-GrContext::~GrContext() { |
- if (NULL == fGpu) { |
+void GrDrawContext::copySurface(GrRenderTarget* dst, GrSurface* src, |
+ const SkIRect& srcRect, const SkIPoint& dstPoint) { |
+ if (!this->prepareToDraw(dst)) { |
return; |
} |
- this->flush(); |
- |
- for (int i = 0; i < fCleanUpData.count(); ++i) { |
- (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo); |
- } |
- |
- SkDELETE(fResourceProvider); |
- SkDELETE(fResourceCache); |
- SkDELETE(fBatchFontCache); |
- SkDELETE(fDrawBuffer); |
- |
- fAARectRenderer->unref(); |
- fOvalRenderer->unref(); |
- |
- fGpu->unref(); |
- SkSafeUnref(fPathRendererChain); |
- SkSafeUnref(fSoftwarePathRenderer); |
+ fDrawTarget->copySurface(dst, src, srcRect, dstPoint); |
} |
-void GrContext::abandonContext() { |
- fResourceProvider->abandon(); |
- // abandon first to so destructors |
- // don't try to free the resources in the API. |
- fResourceCache->abandonAll(); |
- |
- fGpu->contextAbandoned(); |
- |
- // a path renderer may be holding onto resources that |
- // are now unusable |
- SkSafeSetNull(fPathRendererChain); |
- SkSafeSetNull(fSoftwarePathRenderer); |
- |
- SkDELETE(fDrawBuffer); |
- fDrawBuffer = NULL; |
- |
- fBatchFontCache->freeAll(); |
- fLayerCache->freeAll(); |
- fTextBlobCache->freeAll(); |
+void GrDrawContext::drawText(GrPipelineBuilder* pipelineBuilder, GrBatch* batch) { |
+ fDrawTarget->drawBatch(pipelineBuilder, batch); |
} |
-void GrContext::resetContext(uint32_t state) { |
- fGpu->markContextDirty(state); |
-} |
- |
-void GrContext::freeGpuResources() { |
- this->flush(); |
- |
- if (fDrawBuffer) { |
- fDrawBuffer->purgeResources(); |
- } |
- |
- fBatchFontCache->freeAll(); |
- fLayerCache->freeAll(); |
- // a path renderer may be holding onto resources |
- SkSafeSetNull(fPathRendererChain); |
- SkSafeSetNull(fSoftwarePathRenderer); |
- |
- fResourceCache->purgeAllUnlocked(); |
+void GrDrawContext::drawPaths(GrPipelineBuilder* pipelineBuilder, |
+ const GrPathProcessor* pathProc, |
+ const GrPathRange* pathRange, |
+ const void* indices, |
+ int /*GrDrawTarget::PathIndexType*/ indexType, |
+ const float transformValues[], |
+ int /*GrDrawTarget::PathTransformType*/ transformType, |
+ int count, |
+ int /*GrPathRendering::FillType*/ fill) { |
+ fDrawTarget->drawPaths(pipelineBuilder, pathProc, pathRange, |
+ indices, (GrDrawTarget::PathIndexType) indexType, |
+ transformValues, |
+ (GrDrawTarget::PathTransformType) transformType, |
+ count, (GrPathRendering::FillType) fill); |
} |
-void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const { |
- if (resourceCount) { |
- *resourceCount = fResourceCache->getBudgetedResourceCount(); |
- } |
- if (resourceBytes) { |
- *resourceBytes = fResourceCache->getBudgetedResourceBytes(); |
+void GrDrawContext::discard(GrRenderTarget* renderTarget) { |
+ RETURN_IF_ABANDONED |
+ SkASSERT(renderTarget); |
+ AutoCheckFlush acf(fContext); |
+ if (!this->prepareToDraw(renderTarget)) { |
+ return; |
} |
+ fDrawTarget->discard(renderTarget); |
} |
-GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget, |
- SkGpuDevice* gpuDevice, |
- const SkDeviceProperties& |
- leakyProperties, |
- bool enableDistanceFieldFonts) { |
- if (fGpu->caps()->shaderCaps()->pathRenderingSupport() && renderTarget->isMultisampled()) { |
- GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment(); |
- if (sb) { |
- return GrStencilAndCoverTextContext::Create(this, gpuDevice, leakyProperties); |
- } |
- } |
- |
- return GrAtlasTextContext::Create(this, gpuDevice, leakyProperties, enableDistanceFieldFonts); |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
- |
-bool GrContext::isConfigTexturable(GrPixelConfig config) const { |
- return fGpu->caps()->isConfigTexturable(config); |
-} |
- |
-bool GrContext::npotTextureTileSupport() const { |
- return fGpu->caps()->npotTextureTileSupport(); |
-} |
- |
-void GrContext::OverBudgetCB(void* data) { |
- SkASSERT(data); |
- |
- GrContext* context = reinterpret_cast<GrContext*>(data); |
- |
- // Flush the InOrderDrawBuffer to possibly free up some textures |
- context->fFlushToReduceCacheSize = true; |
-} |
- |
-void GrContext::TextBlobCacheOverBudgetCB(void* data) { |
- SkASSERT(data); |
- |
- // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they |
- // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move |
- // drawText calls to below the GrContext level, but this is not trivial because they call |
- // drawPath on SkGpuDevice |
- GrContext* context = reinterpret_cast<GrContext*>(data); |
- context->flush(); |
-} |
- |
-int GrContext::getMaxTextureSize() const { |
- return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride); |
-} |
- |
-int GrContext::getMaxRenderTargetSize() const { |
- return fGpu->caps()->maxRenderTargetSize(); |
-} |
- |
-int GrContext::getMaxSampleCount() const { |
- return fGpu->caps()->maxSampleCount(); |
-} |
- |
-/////////////////////////////////////////////////////////////////////////////// |
- |
-void GrContext::clear(const SkIRect* rect, |
- const GrColor color, |
- bool canIgnoreRect, |
- GrRenderTarget* renderTarget) { |
+void GrDrawContext::clear(GrRenderTarget* renderTarget, |
+ const SkIRect* rect, |
+ const GrColor color, |
+ bool canIgnoreRect) { |
RETURN_IF_ABANDONED |
- ASSERT_OWNED_RESOURCE(renderTarget); |
SkASSERT(renderTarget); |
- AutoCheckFlush acf(this); |
- GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this); |
- GrDrawTarget* target = this->prepareToDraw(); |
- if (NULL == target) { |
+ AutoCheckFlush acf(fContext); |
+ if (!this->prepareToDraw(renderTarget)) { |
return; |
} |
- target->clear(rect, color, canIgnoreRect, renderTarget); |
+ fDrawTarget->clear(rect, color, canIgnoreRect, renderTarget); |
} |
-void GrContext::drawPaint(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& origPaint, |
- const SkMatrix& viewMatrix) { |
+ |
+void GrDrawContext::drawPaint(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& origPaint, |
+ const SkMatrix& viewMatrix) { |
RETURN_IF_ABANDONED |
// set rect to be big enough to fill the space, but not super-huge, so we |
// don't overflow fixed-point implementations |
@@ -335,25 +125,21 @@ void GrContext::drawPaint(GrRenderTarget* rt, |
return; |
} |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawPaintWithPerspective", target); |
- target->drawRect(&pipelineBuilder, |
- paint->getColor(), |
- SkMatrix::I(), |
- r, |
- NULL, |
- &localMatrix); |
+ fDrawTarget->drawBWRect(&pipelineBuilder, |
+ paint->getColor(), |
+ SkMatrix::I(), |
+ r, |
+ NULL, |
+ &localMatrix); |
} |
} |
-//////////////////////////////////////////////////////////////////////////////// |
- |
static inline bool is_irect(const SkRect& r) { |
return SkScalarIsInt(r.fLeft) && SkScalarIsInt(r.fTop) && |
SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom); |
@@ -573,12 +359,12 @@ private: |
SkSTArray<1, Geometry, true> fGeoData; |
}; |
-void GrContext::drawRect(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRect& rect, |
- const GrStrokeInfo* strokeInfo) { |
+void GrDrawContext::drawRect(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& rect, |
+ const GrStrokeInfo* strokeInfo) { |
RETURN_IF_ABANDONED |
if (strokeInfo && strokeInfo->isDashed()) { |
SkPath path; |
@@ -588,14 +374,12 @@ void GrContext::drawRect(GrRenderTarget* rt, |
return; |
} |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawRect", target); |
SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getWidth(); |
// Check if this is a full RT draw and can be replaced with a clear. We don't bother checking |
@@ -625,7 +409,7 @@ void GrContext::drawRect(GrRenderTarget* rt, |
// Will it blend? |
GrColor clearColor; |
if (paint.isOpaqueAndConstantColor(&clearColor)) { |
- target->clear(NULL, clearColor, true, rt); |
+ fDrawTarget->clear(NULL, clearColor, true, rt); |
return; |
} |
} |
@@ -635,26 +419,26 @@ void GrContext::drawRect(GrRenderTarget* rt, |
GrColor color = paint.getColor(); |
SkRect devBoundRect; |
bool needAA = paint.isAntiAlias() && !pipelineBuilder.getRenderTarget()->isMultisampled(); |
- bool doAA = needAA && apply_aa_to_rect(target, &pipelineBuilder, &devBoundRect, rect, width, |
- viewMatrix, color); |
+ bool doAA = needAA && apply_aa_to_rect(fDrawTarget, &pipelineBuilder, &devBoundRect, rect, |
+ width, viewMatrix, color); |
if (doAA) { |
if (width >= 0) { |
- fAARectRenderer->strokeAARect(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- rect, |
- devBoundRect, |
- *strokeInfo); |
+ GrAARectRenderer::StrokeAARect(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ rect, |
+ devBoundRect, |
+ *strokeInfo); |
} else { |
// filled AA rect |
- fAARectRenderer->fillAARect(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- rect, |
- devBoundRect); |
+ GrAARectRenderer::FillAARect(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ rect, |
+ devBoundRect); |
} |
return; |
} |
@@ -675,36 +459,33 @@ void GrContext::drawRect(GrRenderTarget* rt, |
// is enabled because it can cause ugly artifacts. |
pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag, |
snapToPixelCenters); |
- target->drawBatch(&pipelineBuilder, batch); |
+ fDrawTarget->drawBatch(&pipelineBuilder, batch); |
} else { |
// filled BW rect |
- target->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect); |
+ fDrawTarget->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect); |
} |
} |
-void GrContext::drawNonAARectToRect(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRect& rectToDraw, |
- const SkRect& localRect, |
- const SkMatrix* localMatrix) { |
+void GrDrawContext::drawNonAARectToRect(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& rectToDraw, |
+ const SkRect& localRect, |
+ const SkMatrix* localMatrix) { |
RETURN_IF_ABANDONED |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); |
- |
- target->drawRect(&pipelineBuilder, |
- paint.getColor(), |
- viewMatrix, |
- rectToDraw, |
- &localRect, |
- localMatrix); |
+ fDrawTarget->drawBWRect(&pipelineBuilder, |
+ paint.getColor(), |
+ viewMatrix, |
+ rectToDraw, |
+ &localRect, |
+ localMatrix); |
} |
static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords, |
@@ -978,28 +759,25 @@ private: |
SkSTArray<1, Geometry, true> fGeoData; |
}; |
-void GrContext::drawVertices(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- GrPrimitiveType primitiveType, |
- int vertexCount, |
- const SkPoint positions[], |
- const SkPoint texCoords[], |
- const GrColor colors[], |
- const uint16_t indices[], |
- int indexCount) { |
+void GrDrawContext::drawVertices(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ GrPrimitiveType primitiveType, |
+ int vertexCount, |
+ const SkPoint positions[], |
+ const SkPoint texCoords[], |
+ const GrColor colors[], |
+ const uint16_t indices[], |
+ int indexCount) { |
RETURN_IF_ABANDONED |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); |
- |
// TODO clients should give us bounds |
SkRect bounds; |
if (!bounds.setBoundsCheck(positions, vertexCount)) { |
@@ -1022,17 +800,17 @@ void GrContext::drawVertices(GrRenderTarget* rt, |
indexCount, colors, texCoords, |
bounds)); |
- target->drawBatch(&pipelineBuilder, batch); |
+ fDrawTarget->drawBatch(&pipelineBuilder, batch); |
} |
/////////////////////////////////////////////////////////////////////////////// |
-void GrContext::drawRRect(GrRenderTarget*rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRRect& rrect, |
- const GrStrokeInfo& strokeInfo) { |
+void GrDrawContext::drawRRect(GrRenderTarget*rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRRect& rrect, |
+ const GrStrokeInfo& strokeInfo) { |
RETURN_IF_ABANDONED |
if (rrect.isEmpty()) { |
return; |
@@ -1046,77 +824,75 @@ void GrContext::drawRRect(GrRenderTarget*rt, |
return; |
} |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target); |
- |
GrColor color = paint.getColor(); |
- if (!fOvalRenderer->drawRRect(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- paint.isAntiAlias(), |
- rrect, |
- strokeInfo)) { |
+ if (!GrOvalRenderer::DrawRRect(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ paint.isAntiAlias(), |
+ rrect, |
+ strokeInfo)) { |
SkPath path; |
path.setIsVolatile(true); |
path.addRRect(rrect); |
- this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), |
- path, strokeInfo); |
+ this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, |
+ paint.isAntiAlias(), path, strokeInfo); |
} |
} |
/////////////////////////////////////////////////////////////////////////////// |
-void GrContext::drawDRRect(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRRect& outer, |
- const SkRRect& inner) { |
+void GrDrawContext::drawDRRect(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRRect& outer, |
+ const SkRRect& inner) { |
RETURN_IF_ABANDONED |
if (outer.isEmpty()) { |
return; |
} |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- |
- GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
+ return; |
+ } |
GrColor color = paint.getColor(); |
- if (!fOvalRenderer->drawDRRect(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- paint.isAntiAlias(), |
- outer, |
- inner)) { |
+ if (!GrOvalRenderer::DrawDRRect(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ paint.isAntiAlias(), |
+ outer, |
+ inner)) { |
SkPath path; |
path.setIsVolatile(true); |
path.addRRect(inner); |
path.addRRect(outer); |
path.setFillType(SkPath::kEvenOdd_FillType); |
+ |
GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); |
- this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), |
- path, fillRec); |
+ this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, |
+ paint.isAntiAlias(), path, fillRec); |
} |
} |
/////////////////////////////////////////////////////////////////////////////// |
-void GrContext::drawOval(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkRect& oval, |
- const GrStrokeInfo& strokeInfo) { |
+void GrDrawContext::drawOval(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkRect& oval, |
+ const GrStrokeInfo& strokeInfo) { |
RETURN_IF_ABANDONED |
if (oval.isEmpty()) { |
return; |
@@ -1130,28 +906,25 @@ void GrContext::drawOval(GrRenderTarget* rt, |
return; |
} |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER("GrContext::drawOval", target); |
- |
GrColor color = paint.getColor(); |
- if (!fOvalRenderer->drawOval(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- paint.isAntiAlias(), |
- oval, |
- strokeInfo)) { |
+ if (!GrOvalRenderer::DrawOval(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ paint.isAntiAlias(), |
+ oval, |
+ strokeInfo)) { |
SkPath path; |
path.setIsVolatile(true); |
path.addOval(oval); |
- this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), |
- path, strokeInfo); |
+ this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, |
+ paint.isAntiAlias(), path, strokeInfo); |
} |
} |
@@ -1208,12 +981,12 @@ static bool is_nested_rects(GrDrawTarget* target, |
return allEq || allGoE1; |
} |
-void GrContext::drawPath(GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint& paint, |
- const SkMatrix& viewMatrix, |
- const SkPath& path, |
- const GrStrokeInfo& strokeInfo) { |
+void GrDrawContext::drawPath(GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint& paint, |
+ const SkMatrix& viewMatrix, |
+ const SkPath& path, |
+ const GrStrokeInfo& strokeInfo) { |
RETURN_IF_ABANDONED |
if (path.isEmpty()) { |
if (path.isInverseFillType()) { |
@@ -1229,15 +1002,12 @@ void GrContext::drawPath(GrRenderTarget* rt, |
// cache. This presents a potential hazard for buffered drawing. However, |
// the writePixels that uploads to the scratch will perform a flush so we're |
// OK. |
- AutoCheckFlush acf(this); |
+ AutoCheckFlush acf(fContext); |
GrPipelineBuilder pipelineBuilder; |
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf); |
- if (NULL == target) { |
+ if (!this->prepareToDraw(&pipelineBuilder, rt, clip, &paint)) { |
return; |
} |
- GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex()); |
- |
if (!strokeInfo.isDashed()) { |
bool useCoverageAA = paint.isAntiAlias() && |
!pipelineBuilder.getRenderTarget()->isMultisampled(); |
@@ -1246,10 +1016,10 @@ void GrContext::drawPath(GrRenderTarget* rt, |
// Concave AA paths are expensive - try to avoid them for special cases |
SkRect rects[2]; |
- if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, strokeInfo, |
+ if (is_nested_rects(fDrawTarget, &pipelineBuilder, color, viewMatrix, path, strokeInfo, |
rects)) { |
- fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix, |
- rects); |
+ GrAARectRenderer::FillAANestedRects(fDrawTarget, &pipelineBuilder, color, |
+ viewMatrix, rects); |
return; |
} |
} |
@@ -1257,33 +1027,31 @@ void GrContext::drawPath(GrRenderTarget* rt, |
bool isOval = path.isOval(&ovalRect); |
if (isOval && !path.isInverseFillType()) { |
- if (fOvalRenderer->drawOval(target, |
- &pipelineBuilder, |
- color, |
- viewMatrix, |
- paint.isAntiAlias(), |
- ovalRect, |
- strokeInfo)) { |
+ if (GrOvalRenderer::DrawOval(fDrawTarget, |
+ &pipelineBuilder, |
+ color, |
+ viewMatrix, |
+ paint.isAntiAlias(), |
+ ovalRect, |
+ strokeInfo)) { |
return; |
} |
} |
} |
- this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), |
+ this->internalDrawPath(fDrawTarget, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(), |
path, strokeInfo); |
} |
-void GrContext::internalDrawPath(GrDrawTarget* target, |
- GrPipelineBuilder* pipelineBuilder, |
- const SkMatrix& viewMatrix, |
- GrColor color, |
- bool useAA, |
- const SkPath& path, |
- const GrStrokeInfo& strokeInfo) { |
+void GrDrawContext::internalDrawPath(GrDrawTarget* target, |
+ GrPipelineBuilder* pipelineBuilder, |
+ const SkMatrix& viewMatrix, |
+ GrColor color, |
+ bool useAA, |
+ const SkPath& path, |
+ const GrStrokeInfo& strokeInfo) { |
RETURN_IF_ABANDONED |
SkASSERT(!path.isEmpty()); |
- GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target); |
- |
// An Assumption here is that path renderer would use some form of tweaking |
// the src color (either the input alpha or in the frag shader) to implement |
@@ -1302,8 +1070,8 @@ void GrContext::internalDrawPath(GrDrawTarget* target, |
const GrStrokeInfo* strokeInfoPtr = &strokeInfo; |
// Try a 1st time without stroking the path and without allowing the SW renderer |
- GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, |
- *strokeInfoPtr, false, type); |
+ GrPathRenderer* pr = fContext->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, |
+ *strokeInfoPtr, false, type); |
GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); |
if (NULL == pr && strokeInfo.isDashed()) { |
@@ -1316,8 +1084,8 @@ void GrContext::internalDrawPath(GrDrawTarget* target, |
return; |
} |
strokeInfoPtr = &dashlessStrokeInfo; |
- pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, |
- false, type); |
+ pr = fContext->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, |
+ false, type); |
} |
if (NULL == pr) { |
@@ -1340,8 +1108,8 @@ void GrContext::internalDrawPath(GrDrawTarget* target, |
} |
// This time, allow SW renderer |
- pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, |
- true, type); |
+ pr = fContext->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr, |
+ true, type); |
} |
if (NULL == pr) { |
@@ -1354,523 +1122,24 @@ void GrContext::internalDrawPath(GrDrawTarget* target, |
pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeInfoPtr, useCoverageAA); |
} |
-//////////////////////////////////////////////////////////////////////////////// |
- |
-void GrContext::flush(int flagsBitfield) { |
- if (NULL == fDrawBuffer) { |
- return; |
- } |
- |
- if (kDiscard_FlushBit & flagsBitfield) { |
- fDrawBuffer->reset(); |
- } else { |
- fDrawBuffer->flush(); |
- } |
- fResourceCache->notifyFlushOccurred(); |
- fFlushToReduceCacheSize = false; |
-} |
- |
-bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes, |
- const void* inPixels, size_t outRowBytes, void* outPixels) { |
- SkSrcPixelInfo srcPI; |
- if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) { |
- return false; |
- } |
- srcPI.fAlphaType = kUnpremul_SkAlphaType; |
- srcPI.fPixels = inPixels; |
- srcPI.fRowBytes = inRowBytes; |
- |
- SkDstPixelInfo dstPI; |
- dstPI.fColorType = srcPI.fColorType; |
- dstPI.fAlphaType = kPremul_SkAlphaType; |
- dstPI.fPixels = outPixels; |
- dstPI.fRowBytes = outRowBytes; |
- |
- return srcPI.convertPixelsTo(&dstPI, width, height); |
-} |
- |
-bool GrContext::writeSurfacePixels(GrSurface* surface, |
- int left, int top, int width, int height, |
- GrPixelConfig srcConfig, const void* buffer, size_t rowBytes, |
- uint32_t pixelOpsFlags) { |
+bool GrDrawContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder, |
+ GrRenderTarget* rt, |
+ const GrClip& clip, |
+ const GrPaint* paint) { |
RETURN_FALSE_IF_ABANDONED |
- { |
- GrTexture* texture = NULL; |
- if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) && |
- fGpu->canWriteTexturePixels(texture, srcConfig)) { |
- |
- if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && |
- surface->surfacePriv().hasPendingIO()) { |
- this->flush(); |
- } |
- return fGpu->writeTexturePixels(texture, left, top, width, height, |
- srcConfig, buffer, rowBytes); |
- // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the |
- // upload is already flushed. |
- } |
- } |
- |
- // If we didn't do a direct texture write then we upload the pixels to a texture and draw. |
- GrRenderTarget* renderTarget = surface->asRenderTarget(); |
- if (NULL == renderTarget) { |
- return false; |
- } |
- |
- // We ignore the preferred config unless it is a R/B swap of the src config. In that case |
- // we will upload the original src data to a scratch texture but we will spoof it as the swapped |
- // config. This scratch will then have R and B swapped. We correct for this by swapping again |
- // when drawing the scratch to the dst using a conversion effect. |
- bool swapRAndB = false; |
- GrPixelConfig writeConfig = srcConfig; |
- if (GrPixelConfigSwapRAndB(srcConfig) == |
- fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) { |
- writeConfig = GrPixelConfigSwapRAndB(srcConfig); |
- swapRAndB = true; |
- } |
- |
- GrSurfaceDesc desc; |
- desc.fWidth = width; |
- desc.fHeight = height; |
- desc.fConfig = writeConfig; |
- SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc, |
- GrTextureProvider::kApprox_ScratchTexMatch)); |
- if (!texture) { |
- return false; |
- } |
- |
- SkAutoTUnref<const GrFragmentProcessor> fp; |
- SkMatrix textureMatrix; |
- textureMatrix.setIDiv(texture->width(), texture->height()); |
- |
- // allocate a tmp buffer and sw convert the pixels to premul |
- SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0); |
- |
- if (kUnpremul_PixelOpsFlag & pixelOpsFlags) { |
- if (!GrPixelConfigIs8888(srcConfig)) { |
- return false; |
- } |
- fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix)); |
- // handle the unpremul step on the CPU if we couldn't create an effect to do it. |
- if (NULL == fp) { |
- size_t tmpRowBytes = 4 * width; |
- tmpPixels.reset(width * height); |
- if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes, |
- tmpPixels.get())) { |
- return false; |
- } |
- rowBytes = tmpRowBytes; |
- buffer = tmpPixels.get(); |
- } |
- } |
- if (NULL == fp) { |
- fp.reset(GrConfigConversionEffect::Create(texture, |
- swapRAndB, |
- GrConfigConversionEffect::kNone_PMConversion, |
- textureMatrix)); |
- } |
- |
- // Even if the client told us not to flush, we still flush here. The client may have known that |
- // writes to the original surface caused no data hazards, but they can't know that the scratch |
- // we just got is safe. |
- if (texture->surfacePriv().hasPendingIO()) { |
- this->flush(); |
- } |
- if (!fGpu->writeTexturePixels(texture, 0, 0, width, height, |
- writeConfig, buffer, rowBytes)) { |
- return false; |
- } |
- |
- SkMatrix matrix; |
- matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top)); |
- |
- // This function can be called in the midst of drawing another object (e.g., when uploading a |
- // SW-rasterized clip while issuing a draw). So we push the current geometry state before |
- // drawing a rect to the render target. |
- // The bracket ensures we pop the stack if we wind up flushing below. |
- { |
- GrDrawTarget* drawTarget = this->prepareToDraw(); |
- if (!drawTarget) { |
- return false; |
- } |
- |
- GrPipelineBuilder pipelineBuilder; |
- pipelineBuilder.addColorProcessor(fp); |
- pipelineBuilder.setRenderTarget(renderTarget); |
- drawTarget->drawSimpleRect(&pipelineBuilder, |
- GrColor_WHITE, |
- matrix, |
- SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height))); |
- } |
- |
- if (kFlushWrites_PixelOp & pixelOpsFlags) { |
- this->flushSurfaceWrites(surface); |
- } |
+ ASSERT_OWNED_RESOURCE(rt); |
+ SkASSERT(rt && paint); |
+ pipelineBuilder->setFromPaint(*paint, rt, clip); |
return true; |
} |
-// toggles between RGBA and BGRA |
-static SkColorType toggle_colortype32(SkColorType ct) { |
- if (kRGBA_8888_SkColorType == ct) { |
- return kBGRA_8888_SkColorType; |
- } else { |
- SkASSERT(kBGRA_8888_SkColorType == ct); |
- return kRGBA_8888_SkColorType; |
- } |
-} |
- |
-bool GrContext::readRenderTargetPixels(GrRenderTarget* target, |
- int left, int top, int width, int height, |
- GrPixelConfig dstConfig, void* buffer, size_t rowBytes, |
- uint32_t flags) { |
+bool GrDrawContext::prepareToDraw(GrRenderTarget* rt) { |
RETURN_FALSE_IF_ABANDONED |
- ASSERT_OWNED_RESOURCE(target); |
- SkASSERT(target); |
- |
- if (!(kDontFlush_PixelOpsFlag & flags) && target->surfacePriv().hasPendingWrite()) { |
- this->flush(); |
- } |
- |
- // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul. |
- |
- // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll |
- // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read. |
- bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top, |
- width, height, dstConfig, |
- rowBytes); |
- // We ignore the preferred config if it is different than our config unless it is an R/B swap. |
- // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped |
- // config. Then we will call readPixels on the scratch with the swapped config. The swaps during |
- // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from |
- // dstConfig. |
- GrPixelConfig readConfig = dstConfig; |
- bool swapRAndB = false; |
- if (GrPixelConfigSwapRAndB(dstConfig) == |
- fGpu->preferredReadPixelsConfig(dstConfig, target->config())) { |
- readConfig = GrPixelConfigSwapRAndB(readConfig); |
- swapRAndB = true; |
- } |
- |
- bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags); |
- |
- if (unpremul && !GrPixelConfigIs8888(dstConfig)) { |
- // The unpremul flag is only allowed for these two configs. |
- return false; |
- } |
- |
- SkAutoTUnref<GrTexture> tempTexture; |
- |
- // If the src is a texture and we would have to do conversions after read pixels, we instead |
- // do the conversions by drawing the src to a scratch texture. If we handle any of the |
- // conversions in the draw we set the corresponding bool to false so that we don't reapply it |
- // on the read back pixels. |
- GrTexture* src = target->asTexture(); |
- if (src && (swapRAndB || unpremul || flipY)) { |
- // Make the scratch a render so we can read its pixels. |
- GrSurfaceDesc desc; |
- desc.fFlags = kRenderTarget_GrSurfaceFlag; |
- desc.fWidth = width; |
- desc.fHeight = height; |
- desc.fConfig = readConfig; |
- desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
- |
- // When a full read back is faster than a partial we could always make the scratch exactly |
- // match the passed rect. However, if we see many different size rectangles we will trash |
- // our texture cache and pay the cost of creating and destroying many textures. So, we only |
- // request an exact match when the caller is reading an entire RT. |
- GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch; |
- if (0 == left && |
- 0 == top && |
- target->width() == width && |
- target->height() == height && |
- fGpu->fullReadPixelsIsFasterThanPartial()) { |
- match = GrTextureProvider::kExact_ScratchTexMatch; |
- } |
- tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match)); |
- if (tempTexture) { |
- // compute a matrix to perform the draw |
- SkMatrix textureMatrix; |
- textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); |
- textureMatrix.postIDiv(src->width(), src->height()); |
- |
- SkAutoTUnref<const GrFragmentProcessor> fp; |
- if (unpremul) { |
- fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix)); |
- if (fp) { |
- unpremul = false; // we no longer need to do this on CPU after the read back. |
- } |
- } |
- // If we failed to create a PM->UPM effect and have no other conversions to perform then |
- // there is no longer any point to using the scratch. |
- if (fp || flipY || swapRAndB) { |
- if (!fp) { |
- fp.reset(GrConfigConversionEffect::Create( |
- src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion, |
- textureMatrix)); |
- } |
- swapRAndB = false; // we will handle the swap in the draw. |
- |
- // We protect the existing geometry here since it may not be |
- // clear to the caller that a draw operation (i.e., drawSimpleRect) |
- // can be invoked in this method |
- { |
- GrPipelineBuilder pipelineBuilder; |
- SkASSERT(fp); |
- pipelineBuilder.addColorProcessor(fp); |
- |
- pipelineBuilder.setRenderTarget(tempTexture->asRenderTarget()); |
- SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); |
- fDrawBuffer->drawSimpleRect(&pipelineBuilder, |
- GrColor_WHITE, |
- SkMatrix::I(), |
- rect); |
- // we want to read back from the scratch's origin |
- left = 0; |
- top = 0; |
- target = tempTexture->asRenderTarget(); |
- } |
- this->flushSurfaceWrites(target); |
- } |
- } |
- } |
- |
- if (!fGpu->readPixels(target, |
- left, top, width, height, |
- readConfig, buffer, rowBytes)) { |
- return false; |
- } |
- // Perform any conversions we weren't able to perform using a scratch texture. |
- if (unpremul || swapRAndB) { |
- SkDstPixelInfo dstPI; |
- if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) { |
- return false; |
- } |
- dstPI.fAlphaType = kUnpremul_SkAlphaType; |
- dstPI.fPixels = buffer; |
- dstPI.fRowBytes = rowBytes; |
- |
- SkSrcPixelInfo srcPI; |
- srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType; |
- srcPI.fAlphaType = kPremul_SkAlphaType; |
- srcPI.fPixels = buffer; |
- srcPI.fRowBytes = rowBytes; |
- |
- return srcPI.convertPixelsTo(&dstPI, width, height); |
- } |
- return true; |
-} |
- |
-void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) { |
- RETURN_IF_ABANDONED |
- SkASSERT(surface); |
- ASSERT_OWNED_RESOURCE(surface); |
- if (surface->surfacePriv().hasPendingIO()) { |
- this->flush(); |
- } |
- GrRenderTarget* rt = surface->asRenderTarget(); |
- if (fGpu && rt) { |
- fGpu->resolveRenderTarget(rt); |
- } |
-} |
- |
-void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) { |
- RETURN_IF_ABANDONED |
- SkASSERT(renderTarget); |
- ASSERT_OWNED_RESOURCE(renderTarget); |
- AutoCheckFlush acf(this); |
- GrDrawTarget* target = this->prepareToDraw(); |
- if (NULL == target) { |
- return; |
- } |
- target->discard(renderTarget); |
-} |
- |
-void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, |
- const SkIPoint& dstPoint, uint32_t pixelOpsFlags) { |
- RETURN_IF_ABANDONED |
- if (NULL == src || NULL == dst) { |
- return; |
- } |
- ASSERT_OWNED_RESOURCE(src); |
- ASSERT_OWNED_RESOURCE(dst); |
- |
- // Since we're going to the draw target and not GPU, no need to check kNoFlush |
- // here. |
- |
- GrDrawTarget* target = this->prepareToDraw(); |
- if (NULL == target) { |
- return; |
- } |
- target->copySurface(dst, src, srcRect, dstPoint); |
- |
- if (kFlushWrites_PixelOp & pixelOpsFlags) { |
- this->flush(); |
- } |
-} |
- |
-void GrContext::flushSurfaceWrites(GrSurface* surface) { |
- RETURN_IF_ABANDONED |
- if (surface->surfacePriv().hasPendingWrite()) { |
- this->flush(); |
- } |
-} |
- |
-GrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder, |
- GrRenderTarget* rt, |
- const GrClip& clip, |
- const GrPaint* paint, |
- const AutoCheckFlush* acf) { |
- if (NULL == fGpu || NULL == fDrawBuffer) { |
- return NULL; |
- } |
ASSERT_OWNED_RESOURCE(rt); |
- SkASSERT(rt && paint && acf); |
- pipelineBuilder->setFromPaint(*paint, rt, clip); |
- return fDrawBuffer; |
-} |
- |
-GrDrawTarget* GrContext::prepareToDraw() { |
- if (NULL == fGpu) { |
- return NULL; |
- } |
- return fDrawBuffer; |
-} |
- |
-/* |
- * This method finds a path renderer that can draw the specified path on |
- * the provided target. |
- * Due to its expense, the software path renderer has split out so it can |
- * can be individually allowed/disallowed via the "allowSW" boolean. |
- */ |
-GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, |
- const GrPipelineBuilder* pipelineBuilder, |
- const SkMatrix& viewMatrix, |
- const SkPath& path, |
- const GrStrokeInfo& stroke, |
- bool allowSW, |
- GrPathRendererChain::DrawType drawType, |
- GrPathRendererChain::StencilSupport* stencilSupport) { |
- |
- if (NULL == fPathRendererChain) { |
- fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this)); |
- } |
- |
- GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target, |
- pipelineBuilder, |
- viewMatrix, |
- path, |
- stroke, |
- drawType, |
- stencilSupport); |
- |
- if (NULL == pr && allowSW) { |
- if (NULL == fSoftwarePathRenderer) { |
- fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); |
- } |
- pr = fSoftwarePathRenderer; |
- } |
- |
- return pr; |
-} |
- |
-//////////////////////////////////////////////////////////////////////////////// |
-bool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { |
- return fGpu->caps()->isConfigRenderable(config, withMSAA); |
-} |
- |
-int GrContext::getRecommendedSampleCount(GrPixelConfig config, |
- SkScalar dpi) const { |
- if (!this->isConfigRenderable(config, true)) { |
- return 0; |
- } |
- int chosenSampleCount = 0; |
- if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) { |
- if (dpi >= 250.0f) { |
- chosenSampleCount = 4; |
- } else { |
- chosenSampleCount = 16; |
- } |
- } |
- return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? |
- chosenSampleCount : 0; |
-} |
- |
-GrDrawTarget* GrContext::getTextTarget() { |
- return this->prepareToDraw(); |
-} |
- |
-namespace { |
-void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { |
- GrConfigConversionEffect::PMConversion pmToUPM; |
- GrConfigConversionEffect::PMConversion upmToPM; |
- GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM); |
- *pmToUPMValue = pmToUPM; |
- *upmToPMValue = upmToPM; |
-} |
-} |
- |
-const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture, |
- bool swapRAndB, |
- const SkMatrix& matrix) { |
- if (!fDidTestPMConversions) { |
- test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); |
- fDidTestPMConversions = true; |
- } |
- GrConfigConversionEffect::PMConversion pmToUPM = |
- static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion); |
- if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) { |
- return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix); |
- } else { |
- return NULL; |
- } |
-} |
- |
-const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture, |
- bool swapRAndB, |
- const SkMatrix& matrix) { |
- if (!fDidTestPMConversions) { |
- test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion); |
- fDidTestPMConversions = true; |
- } |
- GrConfigConversionEffect::PMConversion upmToPM = |
- static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion); |
- if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) { |
- return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix); |
- } else { |
- return NULL; |
- } |
-} |
- |
-////////////////////////////////////////////////////////////////////////////// |
- |
-void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const { |
- if (maxTextures) { |
- *maxTextures = fResourceCache->getMaxResourceCount(); |
- } |
- if (maxTextureBytes) { |
- *maxTextureBytes = fResourceCache->getMaxResourceBytes(); |
- } |
-} |
- |
-void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) { |
- fResourceCache->setLimits(maxTextures, maxTextureBytes); |
-} |
- |
-////////////////////////////////////////////////////////////////////////////// |
- |
-void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) { |
- fGpu->addGpuTraceMarker(marker); |
- if (fDrawBuffer) { |
- fDrawBuffer->addGpuTraceMarker(marker); |
- } |
-} |
- |
-void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
- fGpu->removeGpuTraceMarker(marker); |
- if (fDrawBuffer) { |
- fDrawBuffer->removeGpuTraceMarker(marker); |
- } |
+ SkASSERT(rt); |
+ return true; |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
@@ -1999,3 +1268,4 @@ BATCH_TEST_DEFINE(VerticesBatch) { |
} |
#endif |
+ |