Avoid making new image snapshot in GPU->GPU SkSurface::draw()

Bug: chromium:943561
Change-Id: I4b5cd545fb31bbaaf7828a2a90a88a0bfb179c87
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/202400
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2019-03-20 15:45:50 -04:00 committed by Skia Commit-Bot
parent 8c70393356
commit c552eaf56a
2 changed files with 37 additions and 0 deletions

View File

@ -204,6 +204,42 @@ bool SkSurface_Gpu::onCharacterize(SkSurfaceCharacterization* characterization)
return true; return true;
} }
void SkSurface_Gpu::onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) {
// If the dst is also GPU we try to not force a new image snapshot (by calling the base class
// onDraw) since that may not always perform the copy-on-write optimization.
auto tryDraw = [&] {
SkASSERT(fDevice->context()->priv().asDirectContext());
GrContext* context = fDevice->context();
GrContext* canvasContext = canvas->getGrContext();
if (!canvasContext) {
return false;
}
if (!canvasContext->priv().asDirectContext() ||
canvasContext->priv().contextID() != context->priv().contextID()) {
return false;
}
GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
if (!rtc) {
return false;
}
sk_sp<GrTextureProxy> srcProxy = rtc->asTextureProxyRef();
if (!srcProxy) {
return false;
}
// Possibly we could skip making an image here if SkGpuDevice exposed a lower level way
// of drawing a texture proxy.
const SkImageInfo info = fDevice->imageInfo();
sk_sp<SkImage> image;
image = sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), kNeedNewImageUniqueID, info.alphaType(),
std::move(srcProxy), info.refColorSpace());
canvas->drawImage(image, x, y, paint);
return true;
};
if (!tryDraw()) {
INHERITED::onDraw(canvas, x, y, paint);
}
}
bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& characterization) const { bool SkSurface_Gpu::isCompatible(const SkSurfaceCharacterization& characterization) const {
GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext(); GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
GrContext* ctx = fDevice->context(); GrContext* ctx = fDevice->context();

View File

@ -36,6 +36,7 @@ public:
GrBackendSemaphore signalSemaphores[]) override; GrBackendSemaphore signalSemaphores[]) override;
bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override; bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override;
bool onCharacterize(SkSurfaceCharacterization*) const override; bool onCharacterize(SkSurfaceCharacterization*) const override;
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) override;
bool isCompatible(const SkSurfaceCharacterization&) const; bool isCompatible(const SkSurfaceCharacterization&) const;
bool onDraw(const SkDeferredDisplayList*) override; bool onDraw(const SkDeferredDisplayList*) override;