Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Unified Diff: src/gpu/GrContext.cpp

Issue 1151283004: Split drawing functionality out of GrContext and into new GrDrawContext (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix no-GPU builds Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.cpp ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrContext.cpp
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 3ed0b6baa26fc37c9483c44b0fa9b30aee85dd7b..550d7ff7c19a4f4c7d9a65cb66c1abe1250c7f03 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -17,6 +17,7 @@
#include "GrCaps.h"
#include "GrContextOptions.h"
#include "GrDefaultGeoProcFactory.h"
+#include "GrDrawContext.h"
#include "GrGpuResource.h"
#include "GrGpuResourcePriv.h"
#include "GrGpu.h"
@@ -53,23 +54,61 @@
#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; }
+#define RETURN_IF_ABANDONED if (fDrawingMgr.abandoned()) { return; }
+#define RETURN_FALSE_IF_ABANDONED if (fDrawingMgr.abandoned()) { return false; }
+#define RETURN_NULL_IF_ABANDONED if (fDrawingMgr.abandoned()) { return NULL; }
-class GrContext::AutoCheckFlush {
-public:
- AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
- ~AutoCheckFlush() {
- if (fContext->fFlushToReduceCacheSize) {
- fContext->flush();
- }
+////////////////////////////////////////////////////////////////////////////////
+
+void GrContext::DrawingMgr::init(GrContext* context) {
+#ifdef IMMEDIATE_MODE
+ fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context));
+#else
+ fDrawTarget = SkNEW_ARGS(GrInOrderDrawBuffer, (context));
+#endif
+
+ fDrawContext = SkNEW_ARGS(GrDrawContext, (context, fDrawTarget));
+}
+
+GrContext::DrawingMgr::~DrawingMgr() {
+ SkSafeUnref(fDrawTarget);
+ SkSafeUnref(fDrawContext);
+}
+
+void GrContext::DrawingMgr::abandon() {
+ SkSafeSetNull(fDrawTarget);
+ fDrawContext->fDrawTarget.reset(NULL);
+ SkSafeSetNull(fDrawContext);
+}
+
+void GrContext::DrawingMgr::purgeResources() {
+ if (fDrawTarget) {
+ fDrawTarget->purgeResources();
+ }
+}
+
+void GrContext::DrawingMgr::reset() {
+ if (fDrawTarget) {
+ fDrawTarget->reset();
}
+}
+
+void GrContext::DrawingMgr::flush() {
+ if (fDrawTarget) {
+ fDrawTarget->flush();
+ }
+}
+
+GrDrawContext* GrContext::DrawingMgr::drawContext() {
+ if (this->abandoned()) {
+ return NULL;
+ }
+ return fDrawContext;
+}
+
+////////////////////////////////////////////////////////////////////////////////
-private:
- GrContext* fContext;
-};
GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
GrContextOptions defaultOptions;
@@ -104,19 +143,16 @@ GrContext::GrContext() : fUniqueID(next_id()) {
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);
+ SkASSERT(!fGpu);
fGpu = GrGpu::Create(backend, backendContext, options, this);
- if (NULL == fGpu) {
+ if (!fGpu) {
return false;
}
this->initCommon();
@@ -130,16 +166,9 @@ void GrContext::initCommon() {
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
+ fDrawingMgr.init(this);
// GrBatchFontCache will eventually replace GrFontCache
fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
@@ -148,7 +177,7 @@ void GrContext::initCommon() {
}
GrContext::~GrContext() {
- if (NULL == fGpu) {
+ if (!fGpu) {
return;
}
@@ -161,10 +190,6 @@ GrContext::~GrContext() {
SkDELETE(fResourceProvider);
SkDELETE(fResourceCache);
SkDELETE(fBatchFontCache);
- SkDELETE(fDrawBuffer);
-
- fAARectRenderer->unref();
- fOvalRenderer->unref();
fGpu->unref();
SkSafeUnref(fPathRendererChain);
@@ -184,8 +209,7 @@ void GrContext::abandonContext() {
SkSafeSetNull(fPathRendererChain);
SkSafeSetNull(fSoftwarePathRenderer);
- SkDELETE(fDrawBuffer);
- fDrawBuffer = NULL;
+ fDrawingMgr.abandon();
fBatchFontCache->freeAll();
fLayerCache->freeAll();
@@ -199,9 +223,7 @@ void GrContext::resetContext(uint32_t state) {
void GrContext::freeGpuResources() {
this->flush();
- if (fDrawBuffer) {
- fDrawBuffer->purgeResources();
- }
+ fDrawingMgr.purgeResources();
fBatchFontCache->freeAll();
fLayerCache->freeAll();
@@ -238,6 +260,10 @@ GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
////////////////////////////////////////////////////////////////////////////////
+bool GrContext::shaderDerivativeSupport() const {
+ return fGpu->caps()->shaderCaps()->shaderDerivativeSupport();
+}
+
bool GrContext::isConfigTexturable(GrPixelConfig config) const {
return fGpu->caps()->isConfigTexturable(config);
}
@@ -278,1093 +304,15 @@ int GrContext::getMaxSampleCount() const {
return fGpu->caps()->maxSampleCount();
}
-///////////////////////////////////////////////////////////////////////////////
-
-void GrContext::clear(const SkIRect* rect,
- const GrColor color,
- bool canIgnoreRect,
- GrRenderTarget* renderTarget) {
- 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) {
- return;
- }
- target->clear(rect, color, canIgnoreRect, renderTarget);
-}
-
-void GrContext::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
- SkRect r;
- r.setLTRB(0, 0,
- SkIntToScalar(rt->width()),
- SkIntToScalar(rt->height()));
- SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
-
- // by definition this fills the entire clip, no need for AA
- if (paint->isAntiAlias()) {
- paint.writable()->setAntiAlias(false);
- }
-
- bool isPerspective = viewMatrix.hasPerspective();
-
- // We attempt to map r by the inverse matrix and draw that. mapRect will
- // map the four corners and bound them with a new rect. This will not
- // produce a correct result for some perspective matrices.
- if (!isPerspective) {
- SkMatrix inverse;
- if (!viewMatrix.invert(&inverse)) {
- SkDebugf("Could not invert matrix\n");
- return;
- }
- inverse.mapRect(&r);
- this->drawRect(rt, clip, *paint, viewMatrix, r);
- } else {
- SkMatrix localMatrix;
- if (!viewMatrix.invert(&localMatrix)) {
- SkDebugf("Could not invert matrix\n");
- return;
- }
-
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER("GrContext::drawPaintWithPerspective", target);
- target->drawRect(&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);
-}
-
-static bool apply_aa_to_rect(GrDrawTarget* target,
- GrPipelineBuilder* pipelineBuilder,
- SkRect* devBoundRect,
- const SkRect& rect,
- SkScalar strokeWidth,
- const SkMatrix& combinedMatrix,
- GrColor color) {
- if (pipelineBuilder->getRenderTarget()->isMultisampled()) {
- return false;
- }
-
-#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
- if (strokeWidth >= 0) {
-#endif
- if (!combinedMatrix.preservesAxisAlignment()) {
- return false;
- }
-
-#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
- } else {
- if (!combinedMatrix.preservesRightAngles()) {
- return false;
- }
- }
-#endif
-
- combinedMatrix.mapRect(devBoundRect, rect);
- if (!combinedMatrix.rectStaysRect()) {
- return true;
- }
-
- if (strokeWidth < 0) {
- return !is_irect(*devBoundRect);
- }
-
- return true;
-}
-
-static inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
- return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
- point.fY >= rect.fTop && point.fY <= rect.fBottom;
-}
-
-class StrokeRectBatch : public GrBatch {
-public:
- struct Geometry {
- GrColor fColor;
- SkMatrix fViewMatrix;
- SkRect fRect;
- SkScalar fStrokeWidth;
- };
-
- static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) {
- return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters));
- }
-
- const char* name() const override { return "StrokeRectBatch"; }
-
- void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- // When this is called on a batch, there is only one geometry bundle
- out->setKnownFourComponents(fGeoData[0].fColor);
- }
-
- void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- out->setKnownSingleComponent(0xff);
- }
-
- void initBatchTracker(const GrPipelineInfo& init) override {
- // Handle any color overrides
- if (init.fColorIgnored) {
- fGeoData[0].fColor = GrColor_ILLEGAL;
- } else if (GrColor_ILLEGAL != init.fOverrideColor) {
- fGeoData[0].fColor = init.fOverrideColor;
- }
-
- // setup batch properties
- fBatch.fColorIgnored = init.fColorIgnored;
- fBatch.fColor = fGeoData[0].fColor;
- fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
- fBatch.fCoverageIgnored = init.fCoverageIgnored;
- }
-
- void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrGeometryProcessor> gp(
- GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
- this->color(),
- this->usesLocalCoords(),
- this->coverageIgnored(),
- this->viewMatrix(),
- SkMatrix::I()));
-
- batchTarget->initDraw(gp, pipeline);
-
- size_t vertexStride = gp->getVertexStride();
-
- SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
-
- Geometry& args = fGeoData[0];
-
- int vertexCount = kVertsPerHairlineRect;
- if (args.fStrokeWidth > 0) {
- vertexCount = kVertsPerStrokeRect;
- }
-
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount,
- &vertexBuffer, &firstVertex);
-
- if (!verts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
-
- SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
-
- GrPrimitiveType primType;
-
- if (args.fStrokeWidth > 0) {;
- primType = kTriangleStrip_GrPrimitiveType;
- args.fRect.sort();
- this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth);
- } else {
- // hairline
- primType = kLineStrip_GrPrimitiveType;
- vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
- vertex[1].set(args.fRect.fRight, args.fRect.fTop);
- vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
- vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
- vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
- }
-
- GrVertices vertices;
- vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
- batchTarget->draw(vertices);
- }
-
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
-
-private:
- StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) {
- this->initClassID<StrokeRectBatch>();
-
- fBatch.fHairline = geometry.fStrokeWidth == 0;
-
- fGeoData.push_back(geometry);
-
- // setup bounds
- fBounds = geometry.fRect;
- SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
- fBounds.outset(rad, rad);
- geometry.fViewMatrix.mapRect(&fBounds);
-
- // If our caller snaps to pixel centers then we have to round out the bounds
- if (snapToPixelCenters) {
- fBounds.roundOut();
- }
- }
-
- /* create a triangle strip that strokes the specified rect. There are 8
- unique vertices, but we repeat the last 2 to close up. Alternatively we
- could use an indices array, and then only send 8 verts, but not sure that
- would be faster.
- */
- void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
- const SkScalar rad = SkScalarHalf(width);
- // TODO we should be able to enable this assert, but we'd have to filter these draws
- // this is a bug
- //SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
-
- verts[0].set(rect.fLeft + rad, rect.fTop + rad);
- verts[1].set(rect.fLeft - rad, rect.fTop - rad);
- verts[2].set(rect.fRight - rad, rect.fTop + rad);
- verts[3].set(rect.fRight + rad, rect.fTop - rad);
- verts[4].set(rect.fRight - rad, rect.fBottom - rad);
- verts[5].set(rect.fRight + rad, rect.fBottom + rad);
- verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
- verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
- verts[8] = verts[0];
- verts[9] = verts[1];
- }
-
-
- GrColor color() const { return fBatch.fColor; }
- bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
- bool colorIgnored() const { return fBatch.fColorIgnored; }
- const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
- bool hairline() const { return fBatch.fHairline; }
- bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
-
- bool onCombineIfPossible(GrBatch* t) override {
- // StrokeRectBatch* that = t->cast<StrokeRectBatch>();
-
- // NonAA stroke rects cannot batch right now
- // TODO make these batchable
- return false;
- }
-
- struct BatchTracker {
- GrColor fColor;
- bool fUsesLocalCoords;
- bool fColorIgnored;
- bool fCoverageIgnored;
- bool fHairline;
- };
-
- const static int kVertsPerHairlineRect = 5;
- const static int kVertsPerStrokeRect = 10;
-
- BatchTracker fBatch;
- 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) {
- RETURN_IF_ABANDONED
- if (strokeInfo && strokeInfo->isDashed()) {
- SkPath path;
- path.setIsVolatile(true);
- path.addRect(rect);
- this->drawPath(rt, clip, paint, viewMatrix, path, *strokeInfo);
- return;
- }
-
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- 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
- // cases where the RT is fully inside a stroke.
- if (width < 0) {
- SkRect rtRect;
- pipelineBuilder.getRenderTarget()->getBoundsRect(&rtRect);
- SkRect clipSpaceRTRect = rtRect;
- bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType();
- if (checkClip) {
- clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX),
- SkIntToScalar(clip.origin().fY));
- }
- // Does the clip contain the entire RT?
- if (!checkClip || clip.quickContains(clipSpaceRTRect)) {
- SkMatrix invM;
- if (!viewMatrix.invert(&invM)) {
- return;
- }
- // Does the rect bound the RT?
- SkPoint srcSpaceRTQuad[4];
- invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
- if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
- rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
- rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
- rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
- // Will it blend?
- GrColor clearColor;
- if (paint.isOpaqueAndConstantColor(&clearColor)) {
- target->clear(NULL, clearColor, true, rt);
- return;
- }
- }
- }
- }
-
- 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);
-
- if (doAA) {
- if (width >= 0) {
- fAARectRenderer->strokeAARect(target,
- &pipelineBuilder,
- color,
- viewMatrix,
- rect,
- devBoundRect,
- *strokeInfo);
- } else {
- // filled AA rect
- fAARectRenderer->fillAARect(target,
- &pipelineBuilder,
- color,
- viewMatrix,
- rect,
- devBoundRect);
- }
- return;
- }
-
- if (width >= 0) {
- StrokeRectBatch::Geometry geometry;
- geometry.fViewMatrix = viewMatrix;
- geometry.fColor = color;
- geometry.fRect = rect;
- geometry.fStrokeWidth = width;
-
- // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic
- bool snapToPixelCenters = (0 == width && !rt->isMultisampled());
- SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixelCenters));
-
- // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
- // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA
- // is enabled because it can cause ugly artifacts.
- pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
- snapToPixelCenters);
- target->drawBatch(&pipelineBuilder, batch);
- } else {
- // filled BW rect
- target->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) {
- RETURN_IF_ABANDONED
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
-
- target->drawRect(&pipelineBuilder,
- paint.getColor(),
- viewMatrix,
- rectToDraw,
- &localRect,
- localMatrix);
-}
-
-static const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords,
- bool hasColors,
- int* colorOffset,
- int* texOffset,
- GrColor color,
- const SkMatrix& viewMatrix,
- bool coverageIgnored) {
- *texOffset = -1;
- *colorOffset = -1;
- uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
- if (hasLocalCoords && hasColors) {
- *colorOffset = sizeof(SkPoint);
- *texOffset = sizeof(SkPoint) + sizeof(GrColor);
- flags |= GrDefaultGeoProcFactory::kColor_GPType |
- GrDefaultGeoProcFactory::kLocalCoord_GPType;
- } else if (hasLocalCoords) {
- *texOffset = sizeof(SkPoint);
- flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
- } else if (hasColors) {
- *colorOffset = sizeof(SkPoint);
- flags |= GrDefaultGeoProcFactory::kColor_GPType;
- }
- return GrDefaultGeoProcFactory::Create(flags, color, hasLocalCoords, coverageIgnored,
- viewMatrix, SkMatrix::I());
-}
-
-class DrawVerticesBatch : public GrBatch {
-public:
- struct Geometry {
- GrColor fColor;
- SkTDArray<SkPoint> fPositions;
- SkTDArray<uint16_t> fIndices;
- SkTDArray<GrColor> fColors;
- SkTDArray<SkPoint> fLocalCoords;
- };
-
- static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveType,
- const SkMatrix& viewMatrix,
- const SkPoint* positions, int vertexCount,
- const uint16_t* indices, int indexCount,
- const GrColor* colors, const SkPoint* localCoords,
- const SkRect& bounds) {
- return SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatrix, positions,
- vertexCount, indices, indexCount, colors,
- localCoords, bounds));
- }
-
- const char* name() const override { return "DrawVerticesBatch"; }
-
- void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
- // When this is called on a batch, there is only one geometry bundle
- if (this->hasColors()) {
- out->setUnknownFourComponents();
- } else {
- out->setKnownFourComponents(fGeoData[0].fColor);
- }
- }
-
- void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
- out->setKnownSingleComponent(0xff);
- }
-
- void initBatchTracker(const GrPipelineInfo& init) override {
- // Handle any color overrides
- if (init.fColorIgnored) {
- fGeoData[0].fColor = GrColor_ILLEGAL;
- } else if (GrColor_ILLEGAL != init.fOverrideColor) {
- fGeoData[0].fColor = init.fOverrideColor;
- }
-
- // setup batch properties
- fBatch.fColorIgnored = init.fColorIgnored;
- fBatch.fColor = fGeoData[0].fColor;
- fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
- fBatch.fCoverageIgnored = init.fCoverageIgnored;
- }
-
- void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- int colorOffset = -1, texOffset = -1;
- SkAutoTUnref<const GrGeometryProcessor> gp(
- set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset,
- &texOffset, this->color(), this->viewMatrix(),
- this->coverageIgnored()));
-
- batchTarget->initDraw(gp, pipeline);
-
- size_t vertexStride = gp->getVertexStride();
-
- SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0)
- + (this->hasColors() ? sizeof(GrColor) : 0));
-
- int instanceCount = fGeoData.count();
-
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(),
- &vertexBuffer, &firstVertex);
-
- if (!verts) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
-
- const GrIndexBuffer* indexBuffer = NULL;
- int firstIndex = 0;
-
- uint16_t* indices = NULL;
- if (this->hasIndices()) {
- indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex);
-
- if (!indices) {
- SkDebugf("Could not allocate indices\n");
- return;
- }
- }
-
- int indexOffset = 0;
- int vertexOffset = 0;
- for (int i = 0; i < instanceCount; i++) {
- const Geometry& args = fGeoData[i];
-
- // TODO we can actually cache this interleaved and then just memcopy
- if (this->hasIndices()) {
- for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) {
- *(indices + indexOffset) = args.fIndices[j] + vertexOffset;
- }
- }
-
- for (int j = 0; j < args.fPositions.count(); ++j) {
- *((SkPoint*)verts) = args.fPositions[j];
- if (this->hasColors()) {
- *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
- }
- if (this->hasLocalCoords()) {
- *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
- }
- verts = (void*)((intptr_t)verts + vertexStride);
- vertexOffset++;
- }
- }
-
- GrVertices vertices;
- if (this->hasIndices()) {
- vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
- firstIndex, this->vertexCount(), this->indexCount());
-
- } else {
- vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
- }
- batchTarget->draw(vertices);
- }
-
- SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
-
-private:
- DrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType,
- const SkMatrix& viewMatrix,
- const SkPoint* positions, int vertexCount,
- const uint16_t* indices, int indexCount,
- const GrColor* colors, const SkPoint* localCoords, const SkRect& bounds) {
- this->initClassID<DrawVerticesBatch>();
- SkASSERT(positions);
-
- fBatch.fViewMatrix = viewMatrix;
- Geometry& installedGeo = fGeoData.push_back(geometry);
-
- installedGeo.fPositions.append(vertexCount, positions);
- if (indices) {
- installedGeo.fIndices.append(indexCount, indices);
- fBatch.fHasIndices = true;
- } else {
- fBatch.fHasIndices = false;
- }
-
- if (colors) {
- installedGeo.fColors.append(vertexCount, colors);
- fBatch.fHasColors = true;
- } else {
- fBatch.fHasColors = false;
- }
-
- if (localCoords) {
- installedGeo.fLocalCoords.append(vertexCount, localCoords);
- fBatch.fHasLocalCoords = true;
- } else {
- fBatch.fHasLocalCoords = false;
- }
- fBatch.fVertexCount = vertexCount;
- fBatch.fIndexCount = indexCount;
- fBatch.fPrimitiveType = primitiveType;
-
- this->setBounds(bounds);
- }
-
- GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; }
- bool batchablePrimitiveType() const {
- return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType ||
- kLines_GrPrimitiveType == fBatch.fPrimitiveType ||
- kPoints_GrPrimitiveType == fBatch.fPrimitiveType;
- }
- GrColor color() const { return fBatch.fColor; }
- bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
- bool colorIgnored() const { return fBatch.fColorIgnored; }
- const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
- bool hasColors() const { return fBatch.fHasColors; }
- bool hasIndices() const { return fBatch.fHasIndices; }
- bool hasLocalCoords() const { return fBatch.fHasLocalCoords; }
- int vertexCount() const { return fBatch.fVertexCount; }
- int indexCount() const { return fBatch.fIndexCount; }
- bool coverageIgnored() const { return fBatch.fCoverageIgnored; }
-
- bool onCombineIfPossible(GrBatch* t) override {
- DrawVerticesBatch* that = t->cast<DrawVerticesBatch>();
-
- if (!this->batchablePrimitiveType() || this->primitiveType() != that->primitiveType()) {
- return false;
- }
-
- SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
-
- // We currently use a uniform viewmatrix for this batch
- if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
- return false;
- }
-
- if (this->hasColors() != that->hasColors()) {
- return false;
- }
-
- if (this->hasIndices() != that->hasIndices()) {
- return false;
- }
-
- if (this->hasLocalCoords() != that->hasLocalCoords()) {
- return false;
- }
-
- if (!this->hasColors() && this->color() != that->color()) {
- return false;
- }
-
- if (this->color() != that->color()) {
- fBatch.fColor = GrColor_ILLEGAL;
- }
- fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
- fBatch.fVertexCount += that->vertexCount();
- fBatch.fIndexCount += that->indexCount();
-
- this->joinBounds(that->bounds());
- return true;
- }
-
- struct BatchTracker {
- GrPrimitiveType fPrimitiveType;
- SkMatrix fViewMatrix;
- GrColor fColor;
- bool fUsesLocalCoords;
- bool fColorIgnored;
- bool fCoverageIgnored;
- bool fHasColors;
- bool fHasIndices;
- bool fHasLocalCoords;
- int fVertexCount;
- int fIndexCount;
- };
-
- BatchTracker fBatch;
- 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) {
- RETURN_IF_ABANDONED
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
-
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
-
- // TODO clients should give us bounds
- SkRect bounds;
- if (!bounds.setBoundsCheck(positions, vertexCount)) {
- SkDebugf("drawVertices call empty bounds\n");
- return;
- }
-
- viewMatrix.mapRect(&bounds);
-
- // If we don't have AA then we outset for a half pixel in each direction to account for
- // snapping
- if (!paint.isAntiAlias()) {
- bounds.outset(0.5f, 0.5f);
- }
-
- DrawVerticesBatch::Geometry geometry;
- geometry.fColor = paint.getColor();
- SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveType, viewMatrix,
- positions, vertexCount, indices,
- indexCount, colors, texCoords,
- bounds));
-
- target->drawBatch(&pipelineBuilder, batch);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrContext::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;
- }
-
- if (strokeInfo.isDashed()) {
- SkPath path;
- path.setIsVolatile(true);
- path.addRRect(rrect);
- this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
- return;
- }
-
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target);
-
- GrColor color = paint.getColor();
- if (!fOvalRenderer->drawRRect(target,
- &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);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrContext::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);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
-
- GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
-
- GrColor color = paint.getColor();
- if (!fOvalRenderer->drawDRRect(target,
- &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);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrContext::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;
- }
-
- if (strokeInfo.isDashed()) {
- SkPath path;
- path.setIsVolatile(true);
- path.addOval(oval);
- this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
- return;
- }
-
- AutoCheckFlush acf(this);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER("GrContext::drawOval", target);
-
- GrColor color = paint.getColor();
- if (!fOvalRenderer->drawOval(target,
- &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);
- }
-}
-
-// Can 'path' be drawn as a pair of filled nested rectangles?
-static bool is_nested_rects(GrDrawTarget* target,
- GrPipelineBuilder* pipelineBuilder,
- GrColor color,
- const SkMatrix& viewMatrix,
- const SkPath& path,
- const SkStrokeRec& stroke,
- SkRect rects[2]) {
- SkASSERT(stroke.isFillStyle());
-
- if (path.isInverseFillType()) {
- return false;
- }
-
- // TODO: this restriction could be lifted if we were willing to apply
- // the matrix to all the points individually rather than just to the rect
- if (!viewMatrix.preservesAxisAlignment()) {
- return false;
- }
-
- SkPath::Direction dirs[2];
- if (!path.isNestedFillRects(rects, dirs)) {
- return false;
- }
-
- if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
- // The two rects need to be wound opposite to each other
- return false;
- }
-
- // Right now, nested rects where the margin is not the same width
- // all around do not render correctly
- const SkScalar* outer = rects[0].asScalars();
- const SkScalar* inner = rects[1].asScalars();
-
- bool allEq = true;
-
- SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
- bool allGoE1 = margin >= SK_Scalar1;
-
- for (int i = 1; i < 4; ++i) {
- SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
- if (temp < SK_Scalar1) {
- allGoE1 = false;
- }
- if (!SkScalarNearlyEqual(margin, temp)) {
- allEq = false;
- }
- }
-
- return allEq || allGoE1;
-}
-
-void GrContext::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()) {
- this->drawPaint(rt, clip, paint, viewMatrix);
- }
- return;
- }
-
- GrColor color = paint.getColor();
-
- // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
- // Scratch textures can be recycled after they are returned to the texture
- // 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);
- GrPipelineBuilder pipelineBuilder;
- GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
- if (NULL == target) {
- return;
- }
-
- GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex());
-
- if (!strokeInfo.isDashed()) {
- bool useCoverageAA = paint.isAntiAlias() &&
- !pipelineBuilder.getRenderTarget()->isMultisampled();
-
- if (useCoverageAA && strokeInfo.getWidth() < 0 && !path.isConvex()) {
- // 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,
- rects)) {
- fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix,
- rects);
- return;
- }
- }
- SkRect ovalRect;
- bool isOval = path.isOval(&ovalRect);
-
- if (isOval && !path.isInverseFillType()) {
- if (fOvalRenderer->drawOval(target,
- &pipelineBuilder,
- color,
- viewMatrix,
- paint.isAntiAlias(),
- ovalRect,
- strokeInfo)) {
- return;
- }
- }
- }
- this->internalDrawPath(target, &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) {
- 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
- // aa. If we have some future driver-mojo path AA that can do the right
- // thing WRT to the blend then we'll need some query on the PR.
- bool useCoverageAA = useAA &&
- !pipelineBuilder->getRenderTarget()->isMultisampled();
-
-
- GrPathRendererChain::DrawType type =
- useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
- GrPathRendererChain::kColor_DrawType;
-
- const SkPath* pathPtr = &path;
- SkTLazy<SkPath> tmpPath;
- 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);
-
- GrStrokeInfo dashlessStrokeInfo(strokeInfo, false);
- if (NULL == pr && strokeInfo.isDashed()) {
- // It didn't work above, so try again with dashed stroke converted to a dashless stroke.
- if (!strokeInfo.applyDashToPath(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) {
- return;
- }
- pathPtr = tmpPath.get();
- if (pathPtr->isEmpty()) {
- return;
- }
- strokeInfoPtr = &dashlessStrokeInfo;
- pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr,
- false, type);
- }
-
- if (NULL == pr) {
- if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMatrix, NULL) &&
- !strokeInfoPtr->isFillStyle()) {
- // It didn't work above, so try again with stroke converted to a fill.
- if (!tmpPath.isValid()) {
- tmpPath.init();
- }
- dashlessStrokeInfo.setResScale(SkScalarAbs(viewMatrix.getMaxScale()));
- if (!dashlessStrokeInfo.applyToPath(tmpPath.get(), *pathPtr)) {
- return;
- }
- pathPtr = tmpPath.get();
- if (pathPtr->isEmpty()) {
- return;
- }
- dashlessStrokeInfo.setFillStyle();
- strokeInfoPtr = &dashlessStrokeInfo;
- }
-
- // This time, allow SW renderer
- pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr,
- true, type);
- }
-
- if (NULL == pr) {
-#ifdef SK_DEBUG
- SkDebugf("Unable to find path renderer compatible with path.\n");
-#endif
- return;
- }
-
- pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeInfoPtr, useCoverageAA);
-}
-
////////////////////////////////////////////////////////////////////////////////
void GrContext::flush(int flagsBitfield) {
- if (NULL == fDrawBuffer) {
- return;
- }
+ RETURN_IF_ABANDONED
if (kDiscard_FlushBit & flagsBitfield) {
- fDrawBuffer->reset();
+ fDrawingMgr.reset();
} else {
- fDrawBuffer->flush();
+ fDrawingMgr.flush();
}
fResourceCache->notifyFlushOccurred();
fFlushToReduceCacheSize = false;
@@ -1412,7 +360,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
// 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) {
+ if (!renderTarget) {
return false;
}
@@ -1451,7 +399,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
}
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) {
+ if (!fp) {
size_t tmpRowBytes = 4 * width;
tmpPixels.reset(width * height);
if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
@@ -1462,7 +410,7 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
buffer = tmpPixels.get();
}
}
- if (NULL == fp) {
+ if (!fp) {
fp.reset(GrConfigConversionEffect::Create(texture,
swapRAndB,
GrConfigConversionEffect::kNone_PMConversion,
@@ -1483,25 +431,18 @@ bool GrContext::writeSurfacePixels(GrSurface* surface,
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)));
+ GrDrawContext* drawContext = this->drawContext();
+ if (!drawContext) {
+ return false;
}
+ GrPaint paint;
+ paint.addColorProcessor(fp);
+
+ SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+
+ drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
+
if (kFlushWrites_PixelOp & pixelOpsFlags) {
this->flushSurfaceWrites(surface);
}
@@ -1614,16 +555,19 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
// clear to the caller that a draw operation (i.e., drawSimpleRect)
// can be invoked in this method
{
- GrPipelineBuilder pipelineBuilder;
- SkASSERT(fp);
- pipelineBuilder.addColorProcessor(fp);
+ GrDrawContext* drawContext = this->drawContext();
+ if (!drawContext) {
+ return false;
+ }
+
+ GrPaint paint;
+ paint.addColorProcessor(fp);
- pipelineBuilder.setRenderTarget(tempTexture->asRenderTarget());
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
- fDrawBuffer->drawSimpleRect(&pipelineBuilder,
- GrColor_WHITE,
- SkMatrix::I(),
- rect);
+
+ drawContext->drawRect(tempTexture->asRenderTarget(), GrClip::WideOpen(), paint,
+ SkMatrix::I(), rect, NULL);
+
// we want to read back from the scratch's origin
left = 0;
top = 0;
@@ -1673,22 +617,10 @@ void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
}
}
-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) {
+ if (!src || !dst) {
return;
}
ASSERT_OWNED_RESOURCE(src);
@@ -1696,12 +628,16 @@ void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
// Since we're going to the draw target and not GPU, no need to check kNoFlush
// here.
+ if (!dst->asRenderTarget()) {
+ return;
+ }
- GrDrawTarget* target = this->prepareToDraw();
- if (NULL == target) {
+ GrDrawContext* drawContext = this->drawContext();
+ if (!drawContext) {
return;
}
- target->copySurface(dst, src, srcRect, dstPoint);
+
+ drawContext->copySurface(dst->asRenderTarget(), src, srcRect, dstPoint);
if (kFlushWrites_PixelOp & pixelOpsFlags) {
this->flush();
@@ -1715,28 +651,6 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) {
}
}
-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.
@@ -1752,7 +666,7 @@ GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
GrPathRendererChain::DrawType drawType,
GrPathRendererChain::StencilSupport* stencilSupport) {
- if (NULL == fPathRendererChain) {
+ if (!fPathRendererChain) {
fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
}
@@ -1764,8 +678,8 @@ GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
drawType,
stencilSupport);
- if (NULL == pr && allowSW) {
- if (NULL == fSoftwarePathRenderer) {
+ if (!pr && allowSW) {
+ if (!fSoftwarePathRenderer) {
fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this));
}
pr = fSoftwarePathRenderer;
@@ -1796,10 +710,6 @@ int GrContext::getRecommendedSampleCount(GrPixelConfig config,
chosenSampleCount : 0;
}
-GrDrawTarget* GrContext::getTextTarget() {
- return this->prepareToDraw();
-}
-
namespace {
void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
GrConfigConversionEffect::PMConversion pmToUPM;
@@ -1861,141 +771,9 @@ void GrContext::setResourceCacheLimits(int maxTextures, size_t 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);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#ifdef GR_TEST_UTILS
-
-BATCH_TEST_DEFINE(StrokeRectBatch) {
- StrokeRectBatch::Geometry geometry;
- geometry.fViewMatrix = GrTest::TestMatrix(random);
- geometry.fColor = GrRandomColor(random);
- geometry.fRect = GrTest::TestRect(random);
- geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f;
-
- return StrokeRectBatch::Create(geometry, random->nextBool());
-}
-
-static uint32_t seed_vertices(GrPrimitiveType type) {
- switch (type) {
- case kTriangles_GrPrimitiveType:
- case kTriangleStrip_GrPrimitiveType:
- case kTriangleFan_GrPrimitiveType:
- return 3;
- case kPoints_GrPrimitiveType:
- return 1;
- case kLines_GrPrimitiveType:
- case kLineStrip_GrPrimitiveType:
- return 2;
- }
- SkFAIL("Incomplete switch\n");
- return 0;
-}
-
-static uint32_t primitive_vertices(GrPrimitiveType type) {
- switch (type) {
- case kTriangles_GrPrimitiveType:
- return 3;
- case kLines_GrPrimitiveType:
- return 2;
- case kTriangleStrip_GrPrimitiveType:
- case kTriangleFan_GrPrimitiveType:
- case kPoints_GrPrimitiveType:
- case kLineStrip_GrPrimitiveType:
- return 1;
- }
- SkFAIL("Incomplete switch\n");
- return 0;
-}
-
-static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
- SkPoint p;
- p.fX = random->nextRangeScalar(min, max);
- p.fY = random->nextRangeScalar(min, max);
- return p;
-}
-
-static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
- SkRandom* random,
- SkTArray<SkPoint>* positions,
- SkTArray<SkPoint>* texCoords, bool hasTexCoords,
- SkTArray<GrColor>* colors, bool hasColors,
- SkTArray<uint16_t>* indices, bool hasIndices) {
- for (uint32_t v = 0; v < count; v++) {
- positions->push_back(random_point(random, min, max));
- if (hasTexCoords) {
- texCoords->push_back(random_point(random, min, max));
- }
- if (hasColors) {
- colors->push_back(GrRandomColor(random));
- }
- if (hasIndices) {
- SkASSERT(maxVertex <= SK_MaxU16);
- indices->push_back(random->nextULessThan((uint16_t)maxVertex));
- }
- }
-}
-
-BATCH_TEST_DEFINE(VerticesBatch) {
- GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimitiveType + 1));
- uint32_t primitiveCount = random->nextRangeU(1, 100);
-
- // TODO make 'sensible' indexbuffers
- SkTArray<SkPoint> positions;
- SkTArray<SkPoint> texCoords;
- SkTArray<GrColor> colors;
- SkTArray<uint16_t> indices;
-
- bool hasTexCoords = random->nextBool();
- bool hasIndices = random->nextBool();
- bool hasColors = random->nextBool();
-
- uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type);
-
- static const SkScalar kMinVertExtent = -100.f;
- static const SkScalar kMaxVertExtent = 100.f;
- randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
- random,
- &positions,
- &texCoords, hasTexCoords,
- &colors, hasColors,
- &indices, hasIndices);
-
- for (uint32_t i = 1; i < primitiveCount; i++) {
- randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
- random,
- &positions,
- &texCoords, hasTexCoords,
- &colors, hasColors,
- &indices, hasIndices);
- }
-
- SkMatrix viewMatrix = GrTest::TestMatrix(random);
- SkRect bounds;
- SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount);
- SkASSERT(result);
-
- viewMatrix.mapRect(&bounds);
-
- DrawVerticesBatch::Geometry geometry;
- geometry.fColor = GrRandomColor(random);
- return DrawVerticesBatch::Create(geometry, type, viewMatrix,
- positions.begin(), vertexCount,
- indices.begin(), hasIndices ? vertexCount : 0,
- colors.begin(),
- texCoords.begin(),
- bounds);
}
-#endif
« no previous file with comments | « src/gpu/GrClipMaskManager.cpp ('k') | src/gpu/GrDefaultPathRenderer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698