diff options
author | 2014-11-05 07:05:34 -0800 | |
---|---|---|
committer | 2014-11-05 07:05:34 -0800 | |
commit | 63b21962867af0f98e12a3ccbe5eef76b7ecc3aa (patch) | |
tree | de7d7e1dc8306de3ceee04f1235ac853b7b22623 /src | |
parent | 0737922ca249dde6187920f491fe2cf3a710cb68 (diff) |
Workaround for PowerVR clear issue.
BUG=skia:
Review URL: https://codereview.chromium.org/701573002
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 71 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.h | 8 | ||||
-rw-r--r-- | src/gpu/GrDrawTargetCaps.h | 5 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrGpu.h | 14 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrInOrderDrawBuffer.h | 9 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.cpp | 12 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 4 |
12 files changed, 101 insertions, 48 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 8f436f2906..08a62a534c 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -546,6 +546,31 @@ void GrDrawTarget::drawPaths(const GrPathRange* pathRange, dstCopy.texture() ? &dstCopy : NULL); } +void GrDrawTarget::clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, + GrRenderTarget* renderTarget) { + if (fCaps->useDrawInsteadOfClear()) { + // This works around a driver bug with clear by drawing a rect instead. + // The driver will ignore a clear if it is the only thing rendered to a + // target before the target is read. + SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height()); + if (NULL == rect || canIgnoreRect || rect->contains(rtRect)) { + rect = &rtRect; + // We first issue a discard() since that may help tilers. + this->discard(renderTarget); + } + AutoStateRestore asr(this, kReset_ASRInit, &SkMatrix::I()); + + this->drawState()->setColor(color); + this->drawState()->disableState(GrDrawState::kClip_StateBit); + this->drawState()->disableState(GrDrawState::kHWAntialias_StateBit); + this->drawState()->setRenderTarget(renderTarget); + + this->drawSimpleRect(*rect); + } else { + this->onClear(rect, color, canIgnoreRect, renderTarget); + } +} + typedef GrTraceMarkerSet::Iter TMIter; void GrDrawTarget::saveActiveTraceMarkers() { if (this->caps()->gpuTracingSupport()) { @@ -969,6 +994,8 @@ void GrDrawTargetCaps::reset() { fGpuTracingSupport = false; fCompressedTexSubImageSupport = false; + fUseDrawInsteadOfClear = false; + fMapBufferFlags = kNone_MapFlags; fMaxRenderTargetSize = 0; @@ -995,6 +1022,8 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) { fGpuTracingSupport = other.fGpuTracingSupport; fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport; + fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear; + fMapBufferFlags = other.fMapBufferFlags; fMaxRenderTargetSize = other.fMaxRenderTargetSize; @@ -1030,25 +1059,29 @@ static SkString map_flags_to_string(uint32_t flags) { SkString GrDrawTargetCaps::dump() const { SkString r; static const char* gNY[] = {"NO", "YES"}; - r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]); - r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); - r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); - r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); - r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); - r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); - r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); - r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]); - r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]); - r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]); - r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]); - r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); - r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); - r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); - r.appendf("Max Texture Size : %d\n", fMaxTextureSize); - r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); - r.appendf("Max Sample Count : %d\n", fMaxSampleCount); - - r.appendf("Map Buffer Support : %s\n", map_flags_to_string(fMapBufferFlags).c_str()); + r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]); + r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); + r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); + r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); + r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]); + r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); + r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); + r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]); + r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]); + r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]); + r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]); + r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); + r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); + r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); + + r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); + + r.appendf("Max Texture Size : %d\n", fMaxTextureSize); + r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); + r.appendf("Max Sample Count : %d\n", fMaxSampleCount); + + r.appendf("Map Buffer Support : %s\n", + map_flags_to_string(fMapBufferFlags).c_str()); static const char* kConfigNames[] = { "Unknown", // kUnknown_GrPixelConfig diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index b1f758a731..47b439e114 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -395,8 +395,8 @@ public: * rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target * can be optionally cleared. */ - virtual void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, - GrRenderTarget* renderTarget) = 0; + void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, + GrRenderTarget* renderTarget); /** * Discards the contents render target. @@ -855,6 +855,10 @@ private: const float transforms[], PathTransformType, GrPathRendering::FillType, const GrDeviceCoordTexture*) = 0; + virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, + GrRenderTarget* renderTarget) = 0; + + virtual void didAddGpuTraceMarker() = 0; virtual void didRemoveGpuTraceMarker() = 0; diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h index e468bc41ab..f13aa53c80 100644 --- a/src/gpu/GrDrawTargetCaps.h +++ b/src/gpu/GrDrawTargetCaps.h @@ -46,6 +46,8 @@ public: bool gpuTracingSupport() const { return fGpuTracingSupport; } bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } + bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } + /** * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and * textures allows partial mappings or full mappings. @@ -104,6 +106,9 @@ protected: bool fGpuTracingSupport : 1; bool fCompressedTexSubImageSupport : 1; + // Driver workaround + bool fUseDrawInsteadOfClear : 1; + uint32_t fMapBufferFlags; int fMaxRenderTargetSize; diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 8cccd35fff..88adb20b60 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -194,13 +194,13 @@ GrIndexBuffer* GrGpu::createInstancedIndexBuffer(const uint16_t* pattern, return buffer; } -void GrGpu::clear(const SkIRect* rect, - GrColor color, - bool canIgnoreRect, - GrRenderTarget* renderTarget) { +void GrGpu::onClear(const SkIRect* rect, + GrColor color, + bool canIgnoreRect, + GrRenderTarget* renderTarget) { SkASSERT(renderTarget); this->handleDirtyContext(); - this->onClear(renderTarget, rect, color, canIgnoreRect); + this->onGpuClear(renderTarget, rect, color, canIgnoreRect); } void GrGpu::clearStencilClip(const SkIRect& rect, diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index 2dcee06d56..d2f13b6c3c 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -266,9 +266,6 @@ public: size_t rowBytes); // GrDrawTarget overrides - virtual void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, - GrRenderTarget* renderTarget) SK_OVERRIDE; - virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; @@ -374,7 +371,8 @@ private: virtual void releaseReservedIndexSpace() SK_OVERRIDE; virtual void geometrySourceWillPush() SK_OVERRIDE; virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE; - + virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect, + GrRenderTarget* renderTarget) SK_OVERRIDE; // called when the 3D context state is unknown. Subclass should emit any // assumed 3D context state and dirty any state cache. @@ -391,11 +389,9 @@ private: virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0; virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0; - // overridden by backend-specific derived class to perform the clear and - // clearRect. NULL rect means clear whole target. If canIgnoreRect is - // true, it is okay to perform a full clear instead of a partial clear - virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color, - bool canIgnoreRect) = 0; + // overridden by backend-specific derived class to perform the clear. + virtual void onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color, + bool canIgnoreRect) = 0; // Overridden by backend specific classes to perform a clear of the stencil clip bits. This is diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index ec8972c95f..64d9cea62e 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -414,8 +414,8 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, this->recordTraceMarkersIfNecessary(); } -void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, - bool canIgnoreRect, GrRenderTarget* renderTarget) { +void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color, + bool canIgnoreRect, GrRenderTarget* renderTarget) { SkIRect r; if (NULL == renderTarget) { renderTarget = this->drawState()->getRenderTarget(); diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 714d822dd5..3d7d526531 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -86,11 +86,6 @@ public: const SkIRect& srcRect, const SkIPoint& dstPoint) SK_OVERRIDE; - virtual void clear(const SkIRect* rect, - GrColor color, - bool canIgnoreRect, - GrRenderTarget* renderTarget) SK_OVERRIDE; - virtual void clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* renderTarget) SK_OVERRIDE; @@ -274,6 +269,10 @@ private: const uint32_t indices[], int count, const float transforms[], PathTransformType, GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; + virtual void onClear(const SkIRect* rect, + GrColor color, + bool canIgnoreRect, + GrRenderTarget* renderTarget) SK_OVERRIDE; virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index ee87a39089..6272aba127 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -380,6 +380,11 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount); } + if (kPowerVR54x_GrGLRenderer == ctxInfo.renderer() || + kPowerVRRogue_GrGLRenderer == ctxInfo.renderer()) { + fUseDrawInsteadOfClear = true; + } + this->initConfigTexturableTable(ctxInfo, gli); this->initConfigRenderableTable(ctxInfo); diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp index 96e26c7826..9f7b05a3c9 100644 --- a/src/gpu/gl/GrGLUtil.cpp +++ b/src/gpu/gl/GrGLUtil.cpp @@ -191,7 +191,7 @@ GrGLVendor GrGLGetVendorFromString(const char* vendorString) { return kQualcomm_GrGLVendor; } if (0 == strcmp(vendorString, "NVIDIA Corporation")) { - return kNVIDIA_GrGLVendor; + return kNVIDIA_GrGLVendor; } } return kOther_GrGLVendor; @@ -204,6 +204,16 @@ GrGLRenderer GrGLGetRendererFromString(const char* rendererString) { } else if (0 == strcmp(rendererString, "NVIDIA Tegra")) { return kTegra2_GrGLRenderer; } + int lastDigit; + int n = sscanf(rendererString, "PowerVR SGX 54%d", &lastDigit); + if (1 == n && lastDigit >= 0 && lastDigit <= 9) { + return kPowerVR54x_GrGLRenderer; + } + static const char kPowerVRRogueStr[] = "PowerVR Rogue"; + if (0 == strncmp(rendererString, kPowerVRRogueStr, + SK_ARRAY_COUNT(kPowerVRRogueStr)-1)) { + return kPowerVRRogue_GrGLRenderer; + } } return kOther_GrGLRenderer; } diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h index 5025db31d6..bc6fdf1757 100644 --- a/src/gpu/gl/GrGLUtil.h +++ b/src/gpu/gl/GrGLUtil.h @@ -43,7 +43,8 @@ enum GrGLVendor { enum GrGLRenderer { kTegra2_GrGLRenderer, kTegra3_GrGLRenderer, - + kPowerVR54x_GrGLRenderer, + kPowerVRRogue_GrGLRenderer, kOther_GrGLRenderer }; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 1a5048aa32..73dd9bb15c 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1356,8 +1356,8 @@ void GrGpuGL::disableScissor() { } } -void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color, - bool canIgnoreRect) { +void GrGpuGL::onGpuClear(GrRenderTarget* target, const SkIRect* rect, GrColor color, + bool canIgnoreRect) { // parent class should never let us get here with no RT SkASSERT(target); GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target); diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 63fcea6e1f..a8851b8e7d 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -134,8 +134,8 @@ private: GrStencilBuffer* sb, GrRenderTarget* rt) SK_OVERRIDE; - virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color, - bool canIgnoreRect) SK_OVERRIDE; + virtual void onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color, + bool canIgnoreRect) SK_OVERRIDE; virtual void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, |