Don't flush on read/write pixels unless necessary
BUG=skia:2889 Committed: https://skia.googlesource.com/skia/+/150723b9298772a5096bec7acd2999c5c9d66239 R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/586073002
This commit is contained in:
parent
ee902cd4f4
commit
8d034a154f
@ -80,9 +80,14 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
|
||||
|
||||
bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
|
||||
bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
|
||||
bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
|
||||
|
||||
private:
|
||||
void addPendingRead() const {
|
||||
this->validate();
|
||||
|
@ -135,6 +135,10 @@ public:
|
||||
*/
|
||||
bool savePixels(const char* filename);
|
||||
|
||||
bool hasPendingRead() const;
|
||||
bool hasPendingWrite() const;
|
||||
bool hasPendingIO() const;
|
||||
|
||||
protected:
|
||||
GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
|
||||
: INHERITED(gpu, isWrapped)
|
||||
|
@ -1347,7 +1347,7 @@ bool GrContext::writeTexturePixels(GrTexture* texture,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(kDontFlush_PixelOpsFlag & flags)) {
|
||||
if (!(kDontFlush_PixelOpsFlag & flags) && texture->hasPendingIO()) {
|
||||
this->flush();
|
||||
}
|
||||
|
||||
@ -1418,7 +1418,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
|
||||
}
|
||||
}
|
||||
|
||||
if (!(kDontFlush_PixelOpsFlag & flags)) {
|
||||
if (!(kDontFlush_PixelOpsFlag & flags) && target->hasPendingWrite()) {
|
||||
this->flush();
|
||||
}
|
||||
|
||||
@ -1578,11 +1578,10 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst, const SkIPoint*
|
||||
}
|
||||
ASSERT_OWNED_RESOURCE(src);
|
||||
|
||||
// Writes pending to the source texture are not tracked, so a flush
|
||||
// is required to ensure that the copy captures the most recent contents
|
||||
// of the source texture. See similar behavior in
|
||||
// GrContext::resolveRenderTarget.
|
||||
this->flush();
|
||||
|
||||
if (src->hasPendingWrite() || dst->hasPendingIO()) {
|
||||
this->flush();
|
||||
}
|
||||
|
||||
GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
|
||||
GrDrawState* drawState = fGpu->drawState();
|
||||
@ -1715,9 +1714,15 @@ bool GrContext::writeRenderTargetPixels(GrRenderTarget* target,
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Usually this could go to fDrawBuffer but currently
|
||||
// writeRenderTargetPixels can be called in the midst of drawing another
|
||||
// object (e.g., when uploading a SW path rendering to the gpu while
|
||||
// drawing a rect) so preserve the current geometry.
|
||||
// drawing a rect). So we always draw directly to GrGpu and preserve the current geometry.
|
||||
// But that means we also have to flush the draw buffer if there is a pending IO operation to
|
||||
// the render target.
|
||||
if (!(kDontFlush_PixelOpsFlag & flags) && target->hasPendingIO()) {
|
||||
this->flush();
|
||||
}
|
||||
SkMatrix matrix;
|
||||
matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
|
||||
GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit, &matrix);
|
||||
|
@ -833,7 +833,7 @@ void GrInOrderDrawBuffer::geometrySourceWillPop(const GeometrySrcState& restored
|
||||
|
||||
void GrInOrderDrawBuffer::recordStateIfNecessary() {
|
||||
if (fStates.empty()) {
|
||||
fStates.push_back() = this->getDrawState();
|
||||
this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawState()));
|
||||
this->addToCmdBuffer(kSetState_Cmd);
|
||||
return;
|
||||
}
|
||||
|
@ -44,3 +44,39 @@ bool GrSurface::savePixels(const char* filename) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrSurface::hasPendingRead() const {
|
||||
const GrTexture* thisTex = this->asTexture();
|
||||
if (thisTex && thisTex->internalHasPendingRead()) {
|
||||
return true;
|
||||
}
|
||||
const GrRenderTarget* thisRT = this->asRenderTarget();
|
||||
if (thisRT && thisRT->internalHasPendingRead()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrSurface::hasPendingWrite() const {
|
||||
const GrTexture* thisTex = this->asTexture();
|
||||
if (thisTex && thisTex->internalHasPendingWrite()) {
|
||||
return true;
|
||||
}
|
||||
const GrRenderTarget* thisRT = this->asRenderTarget();
|
||||
if (thisRT && thisRT->internalHasPendingWrite()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrSurface::hasPendingIO() const {
|
||||
const GrTexture* thisTex = this->asTexture();
|
||||
if (thisTex && thisTex->internalHasPendingIO()) {
|
||||
return true;
|
||||
}
|
||||
const GrRenderTarget* thisRT = this->asRenderTarget();
|
||||
if (thisRT && thisRT->internalHasPendingIO()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user