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);
|
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;
|
typedef GrTraceMarkerSet::Iter TMIter;
|
||||||
void GrDrawTarget::saveActiveTraceMarkers() {
|
void GrDrawTarget::saveActiveTraceMarkers() {
|
||||||
if (this->caps()->gpuTracingSupport()) {
|
if (this->caps()->gpuTracingSupport()) {
|
||||||
@ -969,6 +994,8 @@ void GrDrawTargetCaps::reset() {
|
|||||||
fGpuTracingSupport = false;
|
fGpuTracingSupport = false;
|
||||||
fCompressedTexSubImageSupport = false;
|
fCompressedTexSubImageSupport = false;
|
||||||
|
|
||||||
|
fUseDrawInsteadOfClear = false;
|
||||||
|
|
||||||
fMapBufferFlags = kNone_MapFlags;
|
fMapBufferFlags = kNone_MapFlags;
|
||||||
|
|
||||||
fMaxRenderTargetSize = 0;
|
fMaxRenderTargetSize = 0;
|
||||||
@ -995,6 +1022,8 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
|
|||||||
fGpuTracingSupport = other.fGpuTracingSupport;
|
fGpuTracingSupport = other.fGpuTracingSupport;
|
||||||
fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
|
fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
|
||||||
|
|
||||||
|
fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear;
|
||||||
|
|
||||||
fMapBufferFlags = other.fMapBufferFlags;
|
fMapBufferFlags = other.fMapBufferFlags;
|
||||||
|
|
||||||
fMaxRenderTargetSize = other.fMaxRenderTargetSize;
|
fMaxRenderTargetSize = other.fMaxRenderTargetSize;
|
||||||
@ -1030,25 +1059,29 @@ static SkString map_flags_to_string(uint32_t flags) {
|
|||||||
SkString GrDrawTargetCaps::dump() const {
|
SkString GrDrawTargetCaps::dump() const {
|
||||||
SkString r;
|
SkString r;
|
||||||
static const char* gNY[] = {"NO", "YES"};
|
static const char* gNY[] = {"NO", "YES"};
|
||||||
r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
|
r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]);
|
||||||
r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
|
r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]);
|
||||||
r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
|
r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]);
|
||||||
r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
|
r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]);
|
||||||
r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
|
r.appendf("HW AA Lines Support : %s\n", gNY[fHWAALineSupport]);
|
||||||
r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
|
r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
|
||||||
r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
|
r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
|
||||||
r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
|
r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
|
||||||
r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
|
r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
|
||||||
r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
|
r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
|
||||||
r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]);
|
r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]);
|
||||||
r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
|
r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]);
|
||||||
r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
|
r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]);
|
||||||
r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]);
|
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("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[] = {
|
static const char* kConfigNames[] = {
|
||||||
"Unknown", // kUnknown_GrPixelConfig
|
"Unknown", // kUnknown_GrPixelConfig
|
||||||
|
@ -395,8 +395,8 @@ public:
|
|||||||
* rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
|
* rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
|
||||||
* can be optionally cleared.
|
* can be optionally cleared.
|
||||||
*/
|
*/
|
||||||
virtual void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
|
void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
|
||||||
GrRenderTarget* renderTarget) = 0;
|
GrRenderTarget* renderTarget);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discards the contents render target.
|
* Discards the contents render target.
|
||||||
@ -855,6 +855,10 @@ private:
|
|||||||
const float transforms[], PathTransformType,
|
const float transforms[], PathTransformType,
|
||||||
GrPathRendering::FillType, const GrDeviceCoordTexture*) = 0;
|
GrPathRendering::FillType, const GrDeviceCoordTexture*) = 0;
|
||||||
|
|
||||||
|
virtual void onClear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
|
||||||
|
GrRenderTarget* renderTarget) = 0;
|
||||||
|
|
||||||
|
|
||||||
virtual void didAddGpuTraceMarker() = 0;
|
virtual void didAddGpuTraceMarker() = 0;
|
||||||
virtual void didRemoveGpuTraceMarker() = 0;
|
virtual void didRemoveGpuTraceMarker() = 0;
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
bool gpuTracingSupport() const { return fGpuTracingSupport; }
|
bool gpuTracingSupport() const { return fGpuTracingSupport; }
|
||||||
bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
|
bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
|
||||||
|
|
||||||
|
bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
|
* Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
|
||||||
* textures allows partial mappings or full mappings.
|
* textures allows partial mappings or full mappings.
|
||||||
@ -104,6 +106,9 @@ protected:
|
|||||||
bool fGpuTracingSupport : 1;
|
bool fGpuTracingSupport : 1;
|
||||||
bool fCompressedTexSubImageSupport : 1;
|
bool fCompressedTexSubImageSupport : 1;
|
||||||
|
|
||||||
|
// Driver workaround
|
||||||
|
bool fUseDrawInsteadOfClear : 1;
|
||||||
|
|
||||||
uint32_t fMapBufferFlags;
|
uint32_t fMapBufferFlags;
|
||||||
|
|
||||||
int fMaxRenderTargetSize;
|
int fMaxRenderTargetSize;
|
||||||
|
@ -194,13 +194,13 @@ GrIndexBuffer* GrGpu::createInstancedIndexBuffer(const uint16_t* pattern,
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::clear(const SkIRect* rect,
|
void GrGpu::onClear(const SkIRect* rect,
|
||||||
GrColor color,
|
GrColor color,
|
||||||
bool canIgnoreRect,
|
bool canIgnoreRect,
|
||||||
GrRenderTarget* renderTarget) {
|
GrRenderTarget* renderTarget) {
|
||||||
SkASSERT(renderTarget);
|
SkASSERT(renderTarget);
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
this->onClear(renderTarget, rect, color, canIgnoreRect);
|
this->onGpuClear(renderTarget, rect, color, canIgnoreRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::clearStencilClip(const SkIRect& rect,
|
void GrGpu::clearStencilClip(const SkIRect& rect,
|
||||||
|
@ -266,9 +266,6 @@ public:
|
|||||||
size_t rowBytes);
|
size_t rowBytes);
|
||||||
|
|
||||||
// GrDrawTarget overrides
|
// GrDrawTarget overrides
|
||||||
virtual void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
|
|
||||||
GrRenderTarget* renderTarget) SK_OVERRIDE;
|
|
||||||
|
|
||||||
virtual void clearStencilClip(const SkIRect& rect,
|
virtual void clearStencilClip(const SkIRect& rect,
|
||||||
bool insideClip,
|
bool insideClip,
|
||||||
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
|
GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
|
||||||
@ -374,7 +371,8 @@ private:
|
|||||||
virtual void releaseReservedIndexSpace() SK_OVERRIDE;
|
virtual void releaseReservedIndexSpace() SK_OVERRIDE;
|
||||||
virtual void geometrySourceWillPush() SK_OVERRIDE;
|
virtual void geometrySourceWillPush() SK_OVERRIDE;
|
||||||
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) 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
|
// called when the 3D context state is unknown. Subclass should emit any
|
||||||
// assumed 3D context state and dirty any state cache.
|
// assumed 3D context state and dirty any state cache.
|
||||||
@ -391,11 +389,9 @@ private:
|
|||||||
virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
|
virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
|
||||||
virtual GrIndexBuffer* onCreateIndexBuffer(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
|
// overridden by backend-specific derived class to perform the clear.
|
||||||
// clearRect. NULL rect means clear whole target. If canIgnoreRect is
|
virtual void onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
|
||||||
// true, it is okay to perform a full clear instead of a partial clear
|
bool canIgnoreRect) = 0;
|
||||||
virtual void onClear(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
|
// 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();
|
this->recordTraceMarkersIfNecessary();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color,
|
void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
|
||||||
bool canIgnoreRect, GrRenderTarget* renderTarget) {
|
bool canIgnoreRect, GrRenderTarget* renderTarget) {
|
||||||
SkIRect r;
|
SkIRect r;
|
||||||
if (NULL == renderTarget) {
|
if (NULL == renderTarget) {
|
||||||
renderTarget = this->drawState()->getRenderTarget();
|
renderTarget = this->drawState()->getRenderTarget();
|
||||||
|
@ -86,11 +86,6 @@ public:
|
|||||||
const SkIRect& srcRect,
|
const SkIRect& srcRect,
|
||||||
const SkIPoint& dstPoint) SK_OVERRIDE;
|
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,
|
virtual void clearStencilClip(const SkIRect& rect,
|
||||||
bool insideClip,
|
bool insideClip,
|
||||||
GrRenderTarget* renderTarget) SK_OVERRIDE;
|
GrRenderTarget* renderTarget) SK_OVERRIDE;
|
||||||
@ -274,6 +269,10 @@ private:
|
|||||||
const uint32_t indices[], int count,
|
const uint32_t indices[], int count,
|
||||||
const float transforms[], PathTransformType,
|
const float transforms[], PathTransformType,
|
||||||
GrPathRendering::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
|
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,
|
virtual bool onReserveVertexSpace(size_t vertexSize,
|
||||||
int vertexCount,
|
int vertexCount,
|
||||||
|
@ -380,6 +380,11 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
|||||||
GR_GL_GetIntegerv(gli, GR_GL_MAX_SAMPLES, &fMaxSampleCount);
|
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->initConfigTexturableTable(ctxInfo, gli);
|
||||||
this->initConfigRenderableTable(ctxInfo);
|
this->initConfigRenderableTable(ctxInfo);
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ GrGLVendor GrGLGetVendorFromString(const char* vendorString) {
|
|||||||
return kQualcomm_GrGLVendor;
|
return kQualcomm_GrGLVendor;
|
||||||
}
|
}
|
||||||
if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
|
if (0 == strcmp(vendorString, "NVIDIA Corporation")) {
|
||||||
return kNVIDIA_GrGLVendor;
|
return kNVIDIA_GrGLVendor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return kOther_GrGLVendor;
|
return kOther_GrGLVendor;
|
||||||
@ -204,6 +204,16 @@ GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
|
|||||||
} else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
|
} else if (0 == strcmp(rendererString, "NVIDIA Tegra")) {
|
||||||
return kTegra2_GrGLRenderer;
|
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;
|
return kOther_GrGLRenderer;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ enum GrGLVendor {
|
|||||||
enum GrGLRenderer {
|
enum GrGLRenderer {
|
||||||
kTegra2_GrGLRenderer,
|
kTegra2_GrGLRenderer,
|
||||||
kTegra3_GrGLRenderer,
|
kTegra3_GrGLRenderer,
|
||||||
|
kPowerVR54x_GrGLRenderer,
|
||||||
|
kPowerVRRogue_GrGLRenderer,
|
||||||
kOther_GrGLRenderer
|
kOther_GrGLRenderer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1356,8 +1356,8 @@ void GrGpuGL::disableScissor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpuGL::onClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
|
void GrGpuGL::onGpuClear(GrRenderTarget* target, const SkIRect* rect, GrColor color,
|
||||||
bool canIgnoreRect) {
|
bool canIgnoreRect) {
|
||||||
// parent class should never let us get here with no RT
|
// parent class should never let us get here with no RT
|
||||||
SkASSERT(target);
|
SkASSERT(target);
|
||||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(target);
|
||||||
|
@ -134,8 +134,8 @@ private:
|
|||||||
GrStencilBuffer* sb,
|
GrStencilBuffer* sb,
|
||||||
GrRenderTarget* rt) SK_OVERRIDE;
|
GrRenderTarget* rt) SK_OVERRIDE;
|
||||||
|
|
||||||
virtual void onClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
|
virtual void onGpuClear(GrRenderTarget*, const SkIRect* rect, GrColor color,
|
||||||
bool canIgnoreRect) SK_OVERRIDE;
|
bool canIgnoreRect) SK_OVERRIDE;
|
||||||
|
|
||||||
virtual void onClearStencilClip(GrRenderTarget*,
|
virtual void onClearStencilClip(GrRenderTarget*,
|
||||||
const SkIRect& rect,
|
const SkIRect& rect,
|
||||||
|
Loading…
Reference in New Issue
Block a user