Workaround for PowerVR clear issue.
BUG=skia: Review URL: https://codereview.chromium.org/701573002
This commit is contained in:
parent
0737922ca2
commit
63b2196286
@ -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("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("Map Buffer Support : %s\n", map_flags_to_string(fMapBufferFlags).c_str());
|
||||
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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ enum GrGLVendor {
|
||||
enum GrGLRenderer {
|
||||
kTegra2_GrGLRenderer,
|
||||
kTegra3_GrGLRenderer,
|
||||
|
||||
kPowerVR54x_GrGLRenderer,
|
||||
kPowerVRRogue_GrGLRenderer,
|
||||
kOther_GrGLRenderer
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user