Add a deferred copy surface (take 3)
authorRobert Phillips <robertphillips@google.com>
Thu, 15 Dec 2016 14:23:05 +0000 (09:23 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 15 Dec 2016 15:07:39 +0000 (15:07 +0000)
This CL forces all GrSurface copies to go through a GrSurfaceContext (rather than GrContext).

There is a bit of goofiness going on here until read/writePixels is also consolidated in GrSurfaceContext and a proxy-backed SkImage/SkSurface is added.

This is a reland of https://skia-review.googlesource.com/c/5773/ (Add a deferred copy surface)

Change-Id: Ib8fd96d0569274ef781366eb900ed8ee839ae9bd
Reviewed-on: https://skia-review.googlesource.com/6109
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>

23 files changed:
gm/image_pict.cpp
include/gpu/GrContext.h
include/gpu/GrRenderTargetContext.h
include/gpu/GrSurfaceContext.h
include/gpu/GrTextureContext.h
include/private/GrRenderTargetProxy.h
include/private/GrSurfaceProxy.h
src/core/SkSpecialImage.cpp
src/gpu/GrContext.cpp
src/gpu/GrContextPriv.h
src/gpu/GrRenderTargetContext.cpp
src/gpu/GrRenderTargetContextPriv.h
src/gpu/GrRenderTargetProxy.cpp
src/gpu/GrSurfaceProxy.cpp
src/gpu/GrTextureContext.cpp
src/gpu/SkGpuDevice.cpp
src/image/SkImage_Gpu.cpp
src/image/SkSurface_Gpu.cpp
tests/CopySurfaceTest.cpp
tests/EGLImageTest.cpp
tests/GrTextureStripAtlasTest.cpp
tests/IntTextureTest.cpp
tests/RectangleTextureTest.cpp

index 7f9454923f9d4d6250143a4cad8d8fa95c9d1a33..d2e1ebad95bc85df2a5a171f277b33c8d79e98a1 100644 (file)
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrSurfaceContext.h"
+#include "GrSurfaceProxy.h"
 #include "GrTexture.h"
+#include "GrTextureProxy.h"
 #include "../src/image/SkImage_Gpu.h"
 #endif
 
@@ -209,15 +213,15 @@ class TextureGenerator : public SkImageGenerator {
 public:
     TextureGenerator(GrContext* ctx, const SkImageInfo& info, SkPicture* pic)
         : SkImageGenerator(info)
-        , fCtx(SkRef(ctx))
-    {
-        auto surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
+        , fCtx(SkRef(ctx)) {
+
+        sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info));
         if (surface) {
             surface->getCanvas()->clear(0);
             surface->getCanvas()->translate(-100, -100);
             surface->getCanvas()->drawPicture(pic);
             sk_sp<SkImage> image(surface->makeImageSnapshot());
-            fTexture.reset(SkRef(as_IB(image)->peekTexture()));
+            fProxy = GrSurfaceProxy::MakeWrapped(sk_ref_sp(as_IB(image)->peekTexture()));
         }
     }
 protected:
@@ -227,24 +231,45 @@ protected:
             SkASSERT(ctx == fCtx.get());
         }
 
-        if (!fTexture) {
+        if (!fProxy) {
             return nullptr;
         }
 
+        if (origin.fX == 0 && origin.fY == 0 &&
+            info.width() == fProxy->width() && info.height() == fProxy->height()) {
+            return SkSafeRef(fProxy->instantiate(fCtx->textureProvider())->asTexture());
+        }
+
         // need to copy the subset into a new texture
-        GrSurfaceDesc desc = fTexture->desc();
+        GrSurfaceDesc desc = fProxy->desc();
         desc.fWidth = info.width();
         desc.fHeight = info.height();
 
-        GrTexture* dst = fCtx->textureProvider()->createTexture(desc, SkBudgeted::kNo);
-        fCtx->copySurface(dst, fTexture.get(),
-                          SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height()),
-                          SkIPoint::Make(0, 0));
-        return dst;
+        sk_sp<GrSurfaceContext> dstContext(fCtx->contextPriv().makeDeferredSurfaceContext(
+                                                                            desc,
+                                                                            SkBackingFit::kExact,
+                                                                            SkBudgeted::kNo));
+        if (!dstContext) {
+            return nullptr;
+        }
+
+        if (!dstContext->copy(
+                            fProxy.get(),
+                            SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height()),
+                            SkIPoint::Make(0, 0))) {
+            return nullptr;
+        }
+
+        GrSurface* dstSurf = dstContext->asDeferredSurface()->instantiate(fCtx->textureProvider());
+        if (!dstSurf) {
+            return nullptr;
+        }
+
+        return SkRef(dstSurf->asTexture());
     }
 private:
-    sk_sp<GrContext> fCtx;
-    sk_sp<GrTexture> fTexture;
+    sk_sp<GrContext>      fCtx;
+    sk_sp<GrSurfaceProxy> fProxy;
 };
 static SkImageGenerator* make_tex_generator(GrContext* ctx, SkPicture* pic) {
     const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
index de80b6805eb5643601e909e61dcd9c7880a6b3de..147cf5cb60b36e936105ae0e8685feb79c6e9ceb 100644 (file)
@@ -300,25 +300,6 @@ public:
                             size_t rowBytes,
                             uint32_t pixelOpsFlags = 0);
 
-    /**
-     * Copies a rectangle of texels from src to dst.
-     * @param dst           the surface to copy to.
-     * @param src           the surface to copy from.
-     * @param srcRect       the rectangle of the src that should be copied.
-     * @param dstPoint      the translation applied when writing the srcRect's pixels to the dst.
-     */
-    bool copySurface(GrSurface* dst,
-                     GrSurface* src,
-                     const SkIRect& srcRect,
-                     const SkIPoint& dstPoint);
-
-    /** Helper that copies the whole surface but fails when the two surfaces are not identically
-        sized. */
-    bool copySurface(GrSurface* dst, GrSurface* src) {
-        return this->copySurface(dst, src, SkIRect::MakeWH(dst->width(), dst->height()),
-                                 SkIPoint::Make(0,0));
-    }
-
     /**
      * After this returns any pending writes to the surface will have been issued to the backend 3D API.
      */
index 864055b6371a09bb639b5ca04e7b7ec39160afe5..b86b626df68ec0d26fdc2d20a72ddf431d869761 100644 (file)
@@ -50,8 +50,6 @@ class SK_API GrRenderTargetContext : public GrSurfaceContext {
 public:
     ~GrRenderTargetContext() override;
 
-    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
-
     // TODO: it is odd that we need both the SkPaint in the following 3 methods.
     // We should extract the text parameters from SkPaint and pass them separately
     // akin to GrStyle (GrTextInfo?)
@@ -469,6 +467,8 @@ private:
                           const SkPath&,
                           const GrStyle&);
 
+    bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
+
     // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
     void addDrawOp(const GrPipelineBuilder&, const GrClip&, sk_sp<GrDrawOp>);
 
index f966086afdbf8f755b84a303f9a4b1f8a19a59a9..a772d19c27283fc3b094d8cac4655720cee61064 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef GrSurfaceContext_DEFINED
 #define GrSurfaceContext_DEFINED
 
+#include "../private/GrSurfaceProxy.h"
+
 #include "SkRefCnt.h"
 
 class GrAuditTrail;
@@ -28,7 +30,27 @@ class SK_API GrSurfaceContext : public SkRefCnt {
 public:
     ~GrSurfaceContext() override {}
 
-    virtual bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) = 0;
+    /*
+     * Copy 'src' into the proxy backing this context
+     * @param src       src of pixels
+     * @param srcRect   the subset of 'src' to copy
+     * @param dstPoint  the origin of the 'srcRect' in the destination coordinate space
+     * @return          true if the copy succeeded; false otherwise
+     *
+     * Note: Notionally, 'srcRect' is clipped to 'src's extent with 'dstPoint' being adjusted.
+     *       Then the 'srcRect' offset by 'dstPoint' is clipped against the dst's extent.
+     *       The end result is only valid src pixels and dst pixels will be touched but the copied
+     *       regions will not be shifted.
+     */
+    bool copy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) {
+        return this->onCopy(src, srcRect, dstPoint);
+    }
+
+    bool copy(GrSurfaceProxy* src) {
+        return this->onCopy(src,
+                            SkIRect::MakeWH(src->width(), src->height()),
+                            SkIPoint::Make(0, 0));
+    }
 
     // TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy?
     virtual GrSurfaceProxy* asDeferredSurface() = 0;
@@ -55,6 +77,10 @@ protected:
     SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
 
 private:
+    virtual bool onCopy(GrSurfaceProxy* src,
+                        const SkIRect& srcRect,
+                        const SkIPoint& dstPoint) = 0;
+
     typedef SkRefCnt INHERITED;
 };
 
index 28fe63dc57da687443c51817e0c8162e24cba5ee..ef9613f3c36a5c0fa94a5898d42a363bba6b24ab 100644 (file)
@@ -27,8 +27,6 @@ class SK_API GrTextureContext : public GrSurfaceContext {
 public:
     ~GrTextureContext() override;
 
-    bool copySurface(GrSurface* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
-
     GrSurfaceProxy* asDeferredSurface() override { return fTextureProxy.get(); }
     GrTextureProxy* asDeferredTexture() override { return fTextureProxy.get(); }
     GrRenderTargetProxy* asDeferredRenderTarget() override;
@@ -44,6 +42,8 @@ protected:
 private:
     friend class GrDrawingManager; // for ctor
 
+    bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
+
     GrTextureOpList* getOpList();
 
     GrDrawingManager*            fDrawingManager;
@@ -52,6 +52,8 @@ private:
     // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
     // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
     GrTextureOpList*             fOpList;
+
+    typedef GrSurfaceContext INHERITED;
 };
 
 #endif
index 83107daf6183ba7ff8cc9909995be518b9f17344..7f026ba726420095dc870217292dde15f1e68749 100644 (file)
@@ -53,6 +53,9 @@ public:
 
     GrRenderTarget::Flags testingOnly_getFlags() const;
 
+    // TODO: move this to a priv class!
+    bool refsWrappedObjects() const;
+
 protected:
     friend class GrSurfaceProxy;  // for ctors
 
index 731603b2c9cd93d0c5a492328d1c6d94e335e255..12972c21bed28e9a9fae86accac12f6c1b65498d 100644 (file)
@@ -266,6 +266,20 @@ public:
         return fGpuMemorySize;
     }
 
+    // Helper function that creates a temporary SurfaceContext to perform the copy
+    static sk_sp<GrSurfaceProxy> Copy(GrContext*, GrSurfaceProxy* src,
+                                      SkIRect srcRect, SkBudgeted);
+
+    // Copy the entire 'src'
+    static sk_sp<GrSurfaceProxy> Copy(GrContext* context, GrSurfaceProxy* src,
+                                      SkBudgeted budgeted) {
+        return Copy(context, src, SkIRect::MakeWH(src->width(), src->height()), budgeted);
+    }
+
+    // Test-only entry point - should decrease in use as proxies propagate
+    static sk_sp<GrSurfaceProxy> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
+                                          GrTexture* srcTexture, SkBudgeted budgeted);
+
     bool isWrapped_ForTesting() const;
 
     SkDEBUGCODE(void validate(GrContext*) const;)
index 2567bf1804a58f811e53386402679a1d65e9396c..4f48f7862b54048fe8dc674f2f57c108c154ea49 100644 (file)
@@ -17,6 +17,7 @@
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
+#include "GrSurfaceContext.h"
 #include "GrTexture.h"
 #include "GrSamplerParams.h"
 #include "GrTextureProxy.h"
@@ -346,6 +347,20 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromRaster(const SkIRect& subset,
 #include "GrTexture.h"
 #include "SkImage_Gpu.h"
 
+static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, GrSurfaceProxy* proxy,
+                                          SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
+    // TODO: add GrTextureProxy-backed SkImage_Gpus
+    GrSurface* surf = proxy->instantiate(context->textureProvider());
+    if (!surf) {
+        return nullptr;
+    }
+
+    return sk_make_sp<SkImage_Gpu>(proxy->width(), proxy->height(),
+                                   kNeedNewImageUniqueID, alphaType,
+                                   sk_ref_sp(surf->asTexture()),
+                                   std::move(colorSpace), SkBudgeted::kYes);
+}
+
 class SkSpecialImage_Gpu : public SkSpecialImage_Base {
 public:
     SkSpecialImage_Gpu(const SkIRect& subset,
@@ -478,34 +493,21 @@ public:
                                                    fAlphaType);
     }
 
+    // TODO: move all the logic here into the subset-flavor GrSurfaceProxy::copy?
     sk_sp<SkImage> onMakeTightSubset(const SkIRect& subset) const override {
-        // TODO: add GrTextureProxy-backed SkImage_Gpus
-        GrSurface* surf = fSurfaceProxy->instantiate(fContext->textureProvider());
-        if (!surf) {
-            return nullptr;
-        }
-
+        // TODO: this is problematic since the surfaceProxy could be loose
         if (0 == subset.fLeft && 0 == subset.fTop &&
             fSurfaceProxy->width() == subset.width() &&
             fSurfaceProxy->height() == subset.height()) {
             // The existing GrTexture is already tight so reuse it in the SkImage
-            return sk_make_sp<SkImage_Gpu>(surf->width(), surf->height(),
-                                           kNeedNewImageUniqueID, fAlphaType,
-                                           sk_ref_sp(surf->asTexture()),
-                                           fColorSpace, SkBudgeted::kYes);
+            return wrap_proxy_in_image(fContext, fSurfaceProxy.get(),
+                                       fAlphaType, fColorSpace);
         }
 
-        GrSurfaceDesc desc = fSurfaceProxy->desc();
-        desc.fWidth = subset.width();
-        desc.fHeight = subset.height();
+        sk_sp<GrSurfaceProxy> subsetProxy(GrSurfaceProxy::Copy(fContext, fSurfaceProxy.get(),
+                                                               subset, SkBudgeted::kYes));
 
-        sk_sp<GrTexture> subTx(fContext->textureProvider()->createTexture(desc, SkBudgeted::kYes));
-        if (!subTx) {
-            return nullptr;
-        }
-        fContext->copySurface(subTx.get(), surf, subset, SkIPoint::Make(0, 0));
-        return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
-                                       fAlphaType, std::move(subTx), fColorSpace, SkBudgeted::kYes);
+        return wrap_proxy_in_image(fContext, subsetProxy.get(), fAlphaType, fColorSpace);
     }
 
     sk_sp<SkSurface> onMakeTightSurface(const SkImageFilter::OutputProperties& outProps,
index bcb4f88980c92b68bded3cdb8c385372cba0d915..3e3bc0e6a801236c4c52a280d4efe8f7a490bb67 100644 (file)
@@ -540,43 +540,6 @@ void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) {
     fDrawingManager->prepareSurfaceForExternalIO(surface);
 }
 
-bool GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
-                            const SkIPoint& dstPoint) {
-    ASSERT_SINGLE_OWNER
-    RETURN_FALSE_IF_ABANDONED
-    GR_AUDIT_TRAIL_AUTO_FRAME(&fAuditTrail, "GrContext::copySurface");
-
-    if (!src || !dst) {
-        return false;
-    }
-    ASSERT_OWNED_RESOURCE(src);
-    ASSERT_OWNED_RESOURCE(dst);
-
-    // We don't allow conversion between integer configs and float/fixed configs.
-    if (GrPixelConfigIsSint(dst->config()) != GrPixelConfigIsSint(src->config())) {
-        return false;
-    }
-
-#ifndef ENABLE_MDB
-    // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will
-    // execute the copy immediately. Ensure the data is ready.
-    src->flushWrites();
-#endif
-
-    sk_sp<GrSurfaceContext> surfaceContext(
-        this->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(dst)));
-
-    if (!surfaceContext) {
-        return false;
-    }
-
-    if (!surfaceContext->copySurface(src, srcRect, dstPoint)) {
-        return false;
-    }
-
-    return true;
-}
-
 void GrContext::flushSurfaceWrites(GrSurface* surface) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
@@ -593,23 +556,6 @@ void GrContext::flushSurfaceIO(GrSurface* surface) {
     }
 }
 
-sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
-                                                                  SkBackingFit fit,
-                                                                  SkBudgeted isDstBudgeted) {
-
-    sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc,
-                                                               fit, isDstBudgeted);
-
-    if (proxy->asRenderTargetProxy()) {
-        return this->drawingManager()->makeRenderTargetContext(std::move(proxy), nullptr, nullptr);
-    } else {
-        SkASSERT(proxy->asTextureProxy());
-        return this->drawingManager()->makeTextureContext(std::move(proxy));
-    }
-
-    return nullptr;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 int GrContext::getRecommendedSampleCount(GrPixelConfig config,
                                          SkScalar dpi) const {
@@ -661,6 +607,16 @@ sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurface
     return this->makeWrappedSurfaceContext(std::move(proxy));
 }
 
+sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+                                                                  SkBackingFit fit,
+                                                                  SkBudgeted isDstBudgeted) {
+
+    sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*fContext->caps(), dstDesc,
+                                                               fit, isDstBudgeted);
+
+    return this->makeWrappedSurfaceContext(std::move(proxy));
+}
+
 sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
                                                                    const GrBackendTextureDesc& desc,
                                                                    sk_sp<SkColorSpace> colorSpace,
index 75effa3848cdd42296b126c7f3dd00b5a67331b2..e24a588d1d1258ea7092e707823a72f874f51faf 100644 (file)
@@ -11,6 +11,8 @@
 #include "GrContext.h"
 #include "GrSurfaceContext.h"
 
+class GrSurfaceProxy;
+
 /** Class that adds methods to GrContext that are only intended for use internal to Skia.
     This class is purely a privileged window into GrContext. It should never have additional
     data members or virtual methods. */
index 1ba66acac6df345031d4c52bc6e03a15bd6342a5..ee87dae13b845bd34d3d97493ec654e2c47d406f 100644 (file)
@@ -133,12 +133,20 @@ GrRenderTargetOpList* GrRenderTargetContext::getOpList() {
     return fOpList;
 }
 
-bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect,
-                                        const SkIPoint& dstPoint) {
+// TODO: move this (and GrTextContext::copy) to GrSurfaceContext?
+bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy,
+                                   const SkIRect& srcRect,
+                                   const SkIPoint& dstPoint) {
     ASSERT_SINGLE_OWNER
     RETURN_FALSE_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copySurface");
+    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copy");
+
+    // TODO: defer instantiation until flush time
+    sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->textureProvider())));
+    if (!src) {
+        return false;
+    }
 
     // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
     sk_sp<GrRenderTarget> rt(
@@ -147,7 +155,7 @@ bool GrRenderTargetContext::copySurface(GrSurface* src, const SkIRect& srcRect,
         return false;
     }
 
-    return this->getOpList()->copySurface(rt.get(), src, srcRect, dstPoint);
+    return this->getOpList()->copySurface(rt.get(), src.get(), srcRect, dstPoint);
 }
 
 void GrRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint,
index b3bd72a563edb8bbded8f47d2f5685a463c55f0b..f1548cc9fad0ed3dc7f0bb05f31f627a37ec24eb 100644 (file)
@@ -114,6 +114,10 @@ public:
                                const GrUserStencilSettings* = nullptr,
                                bool snapToCenters = false);
 
+    bool refsWrappedObjects() const {
+        return fRenderTargetContext->fRenderTargetProxy->refsWrappedObjects();
+    }
+
 private:
     explicit GrRenderTargetContextPriv(GrRenderTargetContext* renderTargetContext)
         : fRenderTargetContext(renderTargetContext) {}
index 03637cf9af1a2e89987899c8ca9f9b77387de0f4..882acf660c3ca12d4192848f22972cd6558ff0b3 100644 (file)
@@ -8,6 +8,7 @@
 #include "GrRenderTargetProxy.h"
 
 #include "GrCaps.h"
+#include "GrGpuResourcePriv.h"
 #include "GrRenderTargetOpList.h"
 #include "GrRenderTargetPriv.h"
 #include "GrTextureProvider.h"
@@ -63,3 +64,10 @@ size_t GrRenderTargetProxy::onGpuMemorySize() const {
     return GrSurface::ComputeSize(fDesc, fDesc.fSampleCnt+1, false, SkBackingFit::kApprox == fFit);
 }
 
+bool GrRenderTargetProxy::refsWrappedObjects() const {
+    if (!fTarget) {
+        return false;
+    }
+
+    return fTarget->resourcePriv().refsWrappedObjects();
+}
index 4a0c3480a41c677dc47cc6c0b4383c8f33d65966..780ff8aa449a75d5899ec5b8db1367286ec33497 100644 (file)
@@ -8,8 +8,11 @@
 #include "GrSurfaceProxy.h"
 
 #include "GrCaps.h"
+#include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpuResourcePriv.h"
 #include "GrOpList.h"
+#include "GrSurfaceContext.h"
 #include "GrTextureProvider.h"
 #include "GrTextureRenderTargetProxy.h"
 
@@ -161,3 +164,53 @@ void GrSurfaceProxy::validate(GrContext* context) const {
     INHERITED::validate();
 }
 #endif
+
+sk_sp<GrSurfaceProxy> GrSurfaceProxy::Copy(GrContext* context,
+                                           GrSurfaceProxy* src,
+                                           SkIRect srcRect,
+                                           SkBudgeted budgeted) {
+    if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
+        return nullptr;
+    }
+
+    GrSurfaceDesc dstDesc = src->desc();
+    dstDesc.fWidth = srcRect.width();
+    dstDesc.fHeight = srcRect.height();
+
+    sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
+                                                                            dstDesc,
+                                                                            SkBackingFit::kExact,
+                                                                            budgeted));
+    if (!dstContext) {
+        return nullptr;
+    }
+
+    if (!dstContext->copy(src, srcRect, SkIPoint::Make(0, 0))) {
+        return nullptr;
+    }
+
+    return sk_ref_sp(dstContext->asDeferredSurface());
+}
+
+sk_sp<GrSurfaceProxy> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
+                                               GrTexture* srcTexture, SkBudgeted budgeted) {
+
+    sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
+                                                                            dstDesc,
+                                                                            SkBackingFit::kExact,
+                                                                            budgeted));
+    if (!dstContext) {
+        return nullptr;
+    }
+
+    sk_sp<GrSurfaceProxy> srcProxy(GrSurfaceProxy::MakeWrapped(sk_ref_sp(srcTexture)));
+    if (!srcProxy) {
+        return nullptr;
+    }
+
+    if (!dstContext->copy(srcProxy.get())) {
+        return nullptr;
+    }
+
+    return sk_ref_sp(dstContext->asDeferredSurface());
+}
index 59dae3f0f24f4dffd7262ff8f411f5500a77457e..9f6155127037cf89ad5f9d8309559d92666b9498 100644 (file)
@@ -24,8 +24,7 @@ GrTextureContext::GrTextureContext(GrContext* context,
     : GrSurfaceContext(context, auditTrail, singleOwner)
     , fDrawingManager(drawingMgr)
     , fTextureProxy(std::move(textureProxy))
-    , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList()))
-{
+    , fOpList(SkSafeRef(fTextureProxy->getLastTextureOpList())) {
     SkDEBUGCODE(this->validate();)
 }
 
@@ -62,12 +61,26 @@ GrTextureOpList* GrTextureContext::getOpList() {
     return fOpList;
 }
 
-bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect,
-                                   const SkIPoint& dstPoint) {
+// TODO: move this (and GrRenderTargetContext::copy) to GrSurfaceContext?
+bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
+                              const SkIRect& srcRect,
+                              const SkIPoint& dstPoint) {
     ASSERT_SINGLE_OWNER
     RETURN_FALSE_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copySurface");
+    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrTextureContext::copy");
+
+    // TODO: defer instantiation until flush time
+    sk_sp<GrSurface> src(sk_ref_sp(srcProxy->instantiate(fContext->textureProvider())));
+    if (!src) {
+        return false;
+    }
+\r
+#ifndef ENABLE_MDB\r
+    // We can't yet fully defer copies to textures, so GrTextureContext::copySurface will\r
+    // execute the copy immediately. Ensure the data is ready.\r
+    src->flushWrites();\r
+#endif
 
     // TODO: this needs to be fixed up since it ends the deferrable of the GrTexture
     sk_sp<GrTexture> tex(sk_ref_sp(fTextureProxy->instantiate(fContext->textureProvider())));
@@ -76,7 +89,7 @@ bool GrTextureContext::copySurface(GrSurface* src, const SkIRect& srcRect,
     }
 
     GrTextureOpList* opList = this->getOpList();
-    bool result = opList->copySurface(tex.get(), src, srcRect, dstPoint);
+    bool result = opList->copySurface(tex.get(), src.get(), srcRect, dstPoint);
 
 #ifndef ENABLE_MDB
     GrOpFlushState flushState(fContext->getGpu(), nullptr);
index 8549b0ccf1d9d0ca570a25efe27ea3d713e3093b..a623dd1fdb05cd6591871e21983e0d89713788a7 100644 (file)
@@ -15,6 +15,7 @@
 #include "GrRenderTargetContextPriv.h"
 #include "GrStyle.h"
 #include "GrTextureAdjuster.h"
+#include "GrTextureProxy.h"
 #include "GrTracing.h"
 
 #include "SkCanvasPriv.h"
@@ -262,9 +263,7 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
         if (fRenderTargetContext->wasAbandoned()) {
             return;
         }
-        newRTC->copySurface(fRenderTargetContext->asTexture().get(),
-                            SkIRect::MakeWH(this->width(), this->height()),
-                            SkIPoint::Make(0, 0));
+        newRTC->copy(fRenderTargetContext->asDeferredSurface());
     }
 
     fRenderTargetContext = newRTC;
@@ -1332,19 +1331,15 @@ sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
 }
 
 sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
-    sk_sp<GrTexture> texture(this->accessRenderTargetContext()->asTexture());
-    if (!texture) {
+    sk_sp<GrSurfaceProxy> sProxy(sk_ref_sp(this->accessRenderTargetContext()->asDeferredTexture()));
+    if (!sProxy) {
         // When the device doesn't have a texture, we create a temporary texture.
         // TODO: we should actually only copy the portion of the source needed to apply the image
         // filter
-        texture.reset(fContext->textureProvider()->createTexture(
-            this->accessRenderTargetContext()->desc(), SkBudgeted::kYes));
-        if (!texture) {
-            return nullptr;
-        }
-
-        if (!fContext->copySurface(texture.get(),
-                                   this->accessRenderTargetContext()->accessRenderTarget())) {
+        sProxy = GrSurfaceProxy::Copy(fContext.get(),
+                                      this->accessRenderTargetContext()->asDeferredSurface(),
+                                      SkBudgeted::kYes);
+        if (!sProxy) {
             return nullptr;
         }
     }
@@ -1352,11 +1347,12 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
     const SkImageInfo ii = this->imageInfo();
     const SkIRect srcRect = SkIRect::MakeWH(ii.width(), ii.height());
 
-    return SkSpecialImage::MakeFromGpu(srcRect,
-                                       kNeedNewImageUniqueID_SpecialImage,
-                                       std::move(texture),
-                                       sk_ref_sp(ii.colorSpace()),
-                                       &this->surfaceProps());
+    return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
+                                               srcRect,
+                                               kNeedNewImageUniqueID_SpecialImage,
+                                               sProxy,
+                                               sk_ref_sp(ii.colorSpace()),
+                                               &this->surfaceProps());
 }
 
 void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
index cc11f6dcdb7c0420a71b8c191ab089ddfeb05f28..c347a1f6060c1440db97bc48cfe36a10cb738157 100644 (file)
@@ -13,6 +13,7 @@
 #include "GrBitmapTextureMaker.h"
 #include "GrCaps.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrImageTextureMaker.h"
 #include "GrRenderTargetContext.h"
 #include "GrTextureAdjuster.h"
@@ -153,13 +154,33 @@ sk_sp<SkImage> SkImage_Gpu::onMakeSubset(const SkIRect& subset) const {
     desc.fWidth = subset.width();
     desc.fHeight = subset.height();
 
-    sk_sp<GrTexture> subTx(ctx->textureProvider()->createTexture(desc, fBudgeted));
+    sk_sp<GrSurfaceContext> sContext(ctx->contextPriv().makeDeferredSurfaceContext(
+                                                                        desc,
+                                                                        SkBackingFit::kExact,
+                                                                        fBudgeted));
+    if (!sContext) {
+        return nullptr;
+    }
+
+    // TODO: make gpu images be proxy-backed so we don't need to do this
+    sk_sp<GrSurfaceProxy> tmpSrc(GrSurfaceProxy::MakeWrapped(fTexture));
+    if (!tmpSrc) {
+        return nullptr;
+    }
+
+    if (!sContext->copy(tmpSrc.get(), subset, SkIPoint::Make(0, 0))) {
+        return nullptr;
+    }
+
+    // TODO: make gpu images be proxy-backed so we don't need to do this
+    GrSurface* subTx = sContext->asDeferredSurface()->instantiate(ctx->textureProvider());
     if (!subTx) {
         return nullptr;
     }
-    ctx->copySurface(subTx.get(), fTexture.get(), subset, SkIPoint::Make(0, 0));
+
     return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
-                                   fAlphaType, std::move(subTx), fColorSpace, fBudgeted);
+                                   fAlphaType, sk_ref_sp(subTx->asTexture()),
+                                   fColorSpace, fBudgeted);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
index f99d3c21026cfcd365ad046bb27d6c1bf16c721f..c81c06ed53c0bdd56f17251b5be4dc5301f2e139 100644 (file)
@@ -14,6 +14,7 @@
 #include "SkImage_Base.h"
 #include "SkImage_Gpu.h"
 #include "SkImagePriv.h"
+#include "GrRenderTargetContextPriv.h"
 #include "SkSurface_Base.h"
 
 #if SK_SUPPORT_GPU
@@ -82,29 +83,39 @@ sk_sp<SkSurface> SkSurface_Gpu::onNewSurface(const SkImageInfo& info) {
 }
 
 sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted, SkCopyPixelsMode cpm) {
-    GrRenderTarget* rt = fDevice->accessRenderTargetContext()->accessRenderTarget();
-    if (!rt) {
+    GrRenderTargetContext* rtc = fDevice->accessRenderTargetContext();
+    if (!rtc) {
         return nullptr;
     }
 
-    GrTexture* tex = rt->asTexture();
-    sk_sp<GrTexture> copy;
+    GrContext* ctx = fDevice->context();
+
+    GrSurfaceProxy* srcProxy = rtc->asDeferredSurface();
+    sk_sp<GrSurfaceContext> copyCtx;
     // If the original render target is a buffer originally created by the client, then we don't
     // want to ever retarget the SkSurface at another buffer we create. Force a copy now to avoid
     // copy-on-write.
-    if (kAlways_SkCopyPixelsMode == cpm || !tex || rt->resourcePriv().refsWrappedObjects()) {
-        GrSurfaceDesc desc = fDevice->accessRenderTargetContext()->desc();
-        GrContext* ctx = fDevice->context();
+    if (kAlways_SkCopyPixelsMode == cpm || !srcProxy || rtc->priv().refsWrappedObjects()) {
+        GrSurfaceDesc desc = rtc->desc();
         desc.fFlags = desc.fFlags & ~kRenderTarget_GrSurfaceFlag;
-        copy.reset(ctx->textureProvider()->createTexture(desc, budgeted));
-        if (!copy) {
+
+        copyCtx = ctx->contextPriv().makeDeferredSurfaceContext(desc,
+                                                                SkBackingFit::kExact,
+                                                                budgeted);
+        if (!copyCtx) {
             return nullptr;
         }
-        if (!ctx->copySurface(copy.get(), rt)) {
+
+        if (!copyCtx->copy(srcProxy)) {
             return nullptr;
         }
-        tex = copy.get();
+
+        srcProxy = copyCtx->asDeferredSurface();
     }
+
+    // TODO: add proxy-backed SkImage_Gpu
+    GrTexture* tex = srcProxy->instantiate(ctx->textureProvider())->asTexture();
+
     const SkImageInfo info = fDevice->imageInfo();
     sk_sp<SkImage> image;
     if (tex) {
index 053b456f57ae02e556348358eab2ddca6c35c35a..951d27249ff944ea509565e230a3c5773ee33b1f 100644 (file)
@@ -10,6 +10,9 @@
 
 #if SK_SUPPORT_GPU
 #include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrSurfaceContext.h"
+#include "GrSurfaceProxy.h"
 #include "GrTexture.h"
 #include "GrTextureProvider.h"
 
@@ -68,22 +71,29 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
                             dstDesc.fOrigin = dOrigin;
                             dstDesc.fFlags = dFlags;
 
-                            sk_sp<GrTexture> src(
-                                context->textureProvider()->createTexture(srcDesc, SkBudgeted::kNo,
-                                                                          srcPixels.get(),
-                                                                          kRowBytes));
-                            sk_sp<GrTexture> dst(
-                                context->textureProvider()->createTexture(dstDesc, SkBudgeted::kNo,
-                                                                          dstPixels.get(),
-                                                                          kRowBytes));
+                            sk_sp<GrSurfaceProxy> src(GrSurfaceProxy::MakeDeferred(
+                                                                    *context->caps(),
+                                                                    context->textureProvider(),
+                                                                    srcDesc, SkBudgeted::kNo,
+                                                                    srcPixels.get(),
+                                                                    kRowBytes));
+
+                            sk_sp<GrSurfaceProxy> dst(GrSurfaceProxy::MakeDeferred(
+                                                                    *context->caps(),
+                                                                    context->textureProvider(),
+                                                                    dstDesc, SkBudgeted::kNo,
+                                                                    dstPixels.get(),
+                                                                    kRowBytes));
                             if (!src || !dst) {
                                 ERRORF(reporter,
                                        "Could not create surfaces for copy surface test.");
                                 continue;
                             }
 
-                            bool result
-                                    = context->copySurface(dst.get(), src.get(), srcRect, dstPoint);
+                            sk_sp<GrSurfaceContext> sContext =
+                                            context->contextPriv().makeWrappedSurfaceContext(dst);
+
+                            bool result = sContext->copy(src.get(), srcRect, dstPoint);
 
                             bool expectedResult = true;
                             SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
@@ -120,9 +130,11 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
                                 continue;
                             }
 
+                            GrSurface* dstSurf = dst->instantiate(context->textureProvider());
+
                             sk_memset32(read.get(), 0, kW * kH);
-                            if (!dst->readPixels(0, 0, kW, kH, baseDesc.fConfig, read.get(),
-                                                 kRowBytes)) {
+                            if (!dstSurf->readPixels(0, 0, kW, kH, baseDesc.fConfig, read.get(),
+                                                     kRowBytes)) {
                                 ERRORF(reporter, "Error calling readPixels");
                                 continue;
                             }
index f78a0ea02abdd64280fa90b379de7ab55042cafb..0dcacf9b6bcbd13d3c4460ed9820caec8a3fe3d7 100644 (file)
@@ -10,6 +10,7 @@
 #include "GrContext.h"
 #include "GrContextFactory.h"
 #include "GrShaderCaps.h"
+#include "GrSurfaceContext.h"
 #include "gl/GrGLGpu.h"
 #include "gl/GrGLUtil.h"
 #include "gl/GLTestContext.h"
@@ -40,7 +41,7 @@ static void cleanup(GLTestContext* glctx0, GrGLuint texID0, GLTestContext* glctx
 }
 
 static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context,
-                             GrTexture* externalTexture, uint32_t expectedPixelValues[]) {
+                             GrSurface* externalTexture, uint32_t expectedPixelValues[]) {
     int pixelCnt = externalTexture->width() * externalTexture->height();
     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt);
@@ -76,9 +77,13 @@ static void test_copy_surface(skiatest::Reporter* reporter, GrContext* context,
     copyDesc.fWidth = externalTexture->width();
     copyDesc.fHeight = externalTexture->height();
     copyDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    sk_sp<GrTexture> copy(context->textureProvider()->createTexture(copyDesc, SkBudgeted::kYes));
-    context->copySurface(copy.get(), externalTexture);
-    test_read_pixels(reporter, context, copy.get(), expectedPixelValues);
+
+    sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, copyDesc,
+                                                        externalTexture, SkBudgeted::kYes));
+
+    GrSurface* copySurf = copy->instantiate(context->textureProvider());
+
+    test_read_pixels(reporter, context, copySurf, expectedPixelValues);
 }
 
 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) {
index 60b8a6dcc4601855113be2dc2a7613573f7379ac..bf95cafeb37a7f0b93cc96cb456ba5b9958b3c40 100644 (file)
@@ -9,6 +9,7 @@
 #if SK_SUPPORT_GPU
 
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpu.h"
 #include "GrTextureStripAtlas.h"
 #include "GrTypes.h"
@@ -21,51 +22,98 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo)
     desc.fWidth = 32;
     desc.fHeight = 32;
     desc.fConfig = kRGBA_8888_GrPixelConfig;
-    GrTexture* texture = context->textureProvider()->createTexture(desc, SkBudgeted::kYes,
-                                                                   nullptr, 0);
 
-    GrSurfaceDesc targetDesc = desc;
-    targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;
-    GrTexture* target = context->textureProvider()->createTexture(targetDesc, SkBudgeted::kYes,
-                                                                  nullptr, 0);
+    sk_sp<GrSurfaceProxy> srcProxy;
 
-    SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
-    memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);
-    texture->writePixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, pixels.get());
+    {
+        SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
+        memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);
 
-    // Add a pending read to the texture, and then make it available for reuse.
-    context->copySurface(target, texture);
-    texture->unref();
+        srcProxy = GrSurfaceProxy::MakeDeferred(*context->caps(), context->textureProvider(),
+                                                desc, SkBudgeted::kYes,
+                                                pixels.get(), 0);
+    }
+
+    // Add a pending read to the src texture, and then make it available for reuse.
+    sk_sp<GrSurfaceProxy> targetProxy;
+    GrSurface* srcSurface;
+
+    {
+        GrSurfaceDesc targetDesc = desc;
+        targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;
+
+        // We can't use GrSurfaceProxy::Copy bc we may be changing the dst proxy type
+        sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
+                                                                            targetDesc,
+                                                                            SkBackingFit::kExact,
+                                                                            SkBudgeted::kYes));
+        REPORTER_ASSERT(reporter, dstContext);
+
+        if (!dstContext->copy(srcProxy.get())) {
+            return;
+        }
+
+        targetProxy = sk_ref_sp(dstContext->asDeferredSurface());
+
+        srcSurface = srcProxy->instantiate(context->textureProvider());
+        srcProxy.reset();
+    }
 
     // Create an atlas with parameters that allow it to reuse the texture.
-    GrTextureStripAtlas::Desc atlasDesc;
-    atlasDesc.fContext = context;
-    atlasDesc.fConfig = desc.fConfig;
-    atlasDesc.fWidth = desc.fWidth;
-    atlasDesc.fHeight = desc.fHeight;
-    atlasDesc.fRowHeight = 1;
-    GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
+    GrTextureStripAtlas* atlas;
+
+    {
+        GrTextureStripAtlas::Desc atlasDesc;
+        atlasDesc.fContext = context;
+        atlasDesc.fConfig = desc.fConfig;
+        atlasDesc.fWidth = desc.fWidth;
+        atlasDesc.fHeight = desc.fHeight;
+        atlasDesc.fRowHeight = 1;
+        atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
+    }
 
     // Write to the atlas' texture.
-    SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
-    size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
-    SkBitmap bitmap;
-    bitmap.allocPixels(info, rowBytes);
-    memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
-    int row = atlas->lockRow(bitmap);
-    if (!context->caps()->preferVRAMUseOverFlushes())
-        REPORTER_ASSERT(reporter, texture == atlas->getTexture());
+    int lockedRow;
+
+    {
+        SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
+        size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
+        SkBitmap bitmap;
+        bitmap.allocPixels(info, rowBytes);
+        memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
+        lockedRow = atlas->lockRow(bitmap);
+    }
 
     // The atlas' use of its texture shouldn't change which pixels got copied to the target.
-    SkAutoTMalloc<uint32_t> actualPixels(desc.fWidth * desc.fHeight);
-    bool success = target->readPixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig,
-                                      actualPixels.get());
-    REPORTER_ASSERT(reporter, success);
-    REPORTER_ASSERT(reporter,
-                    !memcmp(pixels.get(), actualPixels.get(),
-                            sizeof(uint32_t) * desc.fWidth * desc.fHeight));
-    target->unref();
-    atlas->unlockRow(row);
+    {
+        SkAutoTMalloc<uint8_t> actualPixels(sizeof(uint32_t) * desc.fWidth * desc.fHeight);
+
+        // TODO: move readPixels to GrSurfaceProxy?
+        GrSurface* surf = targetProxy->instantiate(context->textureProvider());
+
+        bool success = surf->readPixels(0, 0, desc.fWidth, desc.fHeight,
+                                        kRGBA_8888_GrPixelConfig, actualPixels.get());
+        REPORTER_ASSERT(reporter, success);
+
+        bool good = true;
+
+        const uint8_t* bytes = actualPixels.get();
+        for (size_t i = 0; i < sizeof(uint32_t) * desc.fWidth * desc.fHeight; ++i, ++bytes) {
+            if (0xFF != *bytes) {
+                good = false;
+                break;
+            }
+        }
+
+        REPORTER_ASSERT(reporter, good);
+    }
+
+    if (!context->caps()->preferVRAMUseOverFlushes()) {
+        // This is kindof dodgy since we released it!
+        REPORTER_ASSERT(reporter, srcSurface == atlas->getTexture());
+    }
+
+    atlas->unlockRow(lockedRow);
 }
 
 #endif
index a6eaf98aeade13a1ce9c30493d8fd63384eba95a..5e3fde2f754c99d97611eea6a1124788bec7b8aa 100644 (file)
@@ -95,40 +95,48 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) {
     REPORTER_ASSERT(reporter, !success);
 
     // Test that copying from one integer texture to another succeeds.
-    sk_sp<GrTexture> copy(context->textureProvider()->createTexture(desc, SkBudgeted::kYes));
-    REPORTER_ASSERT(reporter, copy);
-    if (!copy) {
-        return;
-    }
-    success = context->copySurface(copy.get(), texture.get());
-    REPORTER_ASSERT(reporter, success);
-    if (!success) {
-        return;
-    }
-    sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
-    success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get());
-    REPORTER_ASSERT(reporter, success);
-    if (success) {
-        check_pixels(reporter, kS, kS, testData.get(), readData.get());
+    {
+        sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, desc,
+                                                            texture.get(), SkBudgeted::kYes));
+        REPORTER_ASSERT(reporter, copy);
+        if (!copy) {
+            return;
+        }
+
+        GrSurface* copySurface = copy->instantiate(context->textureProvider());
+        REPORTER_ASSERT(reporter, copySurface);
+        if (!copySurface) {
+            return;
+        }
+
+        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
+        success = copySurface->readPixels(0, 0, kS, kS,
+                                          kRGBA_8888_sint_GrPixelConfig, readData.get());
+        REPORTER_ASSERT(reporter, success);
+        if (success) {
+            check_pixels(reporter, kS, kS, testData.get(), readData.get());
+        }
     }
 
-    // Test that copying to a non-integer texture fails.
-    GrSurfaceDesc nonIntDesc = desc;
-    nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig;
-    copy.reset(context->textureProvider()->createTexture(nonIntDesc, SkBudgeted::kYes));
-    REPORTER_ASSERT(reporter, copy);
-    if (!copy) {
-        return;
+
+    // Test that copying to a non-integer (8888) texture fails.
+    {
+        GrSurfaceDesc nonIntDesc = desc;
+        nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig;
+
+        sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, nonIntDesc,
+                                                            texture.get(), SkBudgeted::kYes));
+        REPORTER_ASSERT(reporter, !copy);
     }
-    success = context->copySurface(copy.get(), texture.get());
-    REPORTER_ASSERT(reporter, !success);
-    nonIntDesc.fConfig = kRGBA_half_GrPixelConfig;
-    copy.reset(context->textureProvider()->createTexture(nonIntDesc, SkBudgeted::kYes));
-    REPORTER_ASSERT(reporter, copy ||
-                    !context->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig));
-    if (copy) {
-        success = context->copySurface(copy.get(), texture.get());
-        REPORTER_ASSERT(reporter, !success);
+
+    // Test that copying to a non-integer (RGBA_half) texture fails.
+    if (context->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
+        GrSurfaceDesc nonIntDesc = desc;
+        nonIntDesc.fConfig = kRGBA_half_GrPixelConfig;
+
+        sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, nonIntDesc,
+                                                            texture.get(), SkBudgeted::kYes));
+        REPORTER_ASSERT(reporter, !copy);
     }
 
     // We overwrite the top left quarter of the texture with the bottom right quarter of the
index cc0c4d1e315676c768378496823568ba875cb8ba..587160448c81967beb2d84197b0c1fde2db15773 100644 (file)
@@ -15,7 +15,7 @@
 #include "gl/GLTestContext.h"
 
 static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context,
-                             GrTexture* texture, uint32_t expectedPixelValues[]) {
+                             GrSurface* texture, uint32_t expectedPixelValues[]) {
     int pixelCnt = texture->width() * texture->height();
     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt);
@@ -52,22 +52,30 @@ static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context,
 }
 
 static void test_copy_surface_src(skiatest::Reporter* reporter, GrContext* context,
-                                  GrTexture* rectangleTexture, uint32_t expectedPixelValues[]) {
+                                  GrTexture* rectTexture, uint32_t expectedPixelValues[]) {
+    GrSurfaceDesc copyDstDesc;
+    copyDstDesc.fConfig = kRGBA_8888_GrPixelConfig;
+    copyDstDesc.fWidth = rectTexture->width();
+    copyDstDesc.fHeight = rectTexture->height();
+
     for (auto flags : {kNone_GrSurfaceFlags, kRenderTarget_GrSurfaceFlag}) {
-        GrSurfaceDesc copyDstDesc;
-        copyDstDesc.fConfig = kRGBA_8888_GrPixelConfig;
-        copyDstDesc.fWidth = rectangleTexture->width();
-        copyDstDesc.fHeight = rectangleTexture->height();
         copyDstDesc.fFlags = flags;
-        sk_sp<GrTexture> dst(
-                context->textureProvider()->createTexture(copyDstDesc, SkBudgeted::kYes));
-        context->copySurface(dst.get(), rectangleTexture);
-        test_read_pixels(reporter, context, dst.get(), expectedPixelValues);
+
+        sk_sp<GrSurfaceProxy> dst(GrSurfaceProxy::TestCopy(context, copyDstDesc,
+                                                           rectTexture, SkBudgeted::kYes));
+
+        GrSurface* dstSurf = dst->instantiate(context->textureProvider());
+
+        test_read_pixels(reporter, context, dstSurf, expectedPixelValues);
     }
 }
 
 static void test_copy_surface_dst(skiatest::Reporter* reporter, GrContext* context,
                                   GrTexture* rectangleTexture) {
+
+    sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
+                                                                    sk_ref_sp(rectangleTexture)));
+
     int pixelCnt = rectangleTexture->width() * rectangleTexture->height();
     SkAutoTMalloc<uint32_t> pixels(pixelCnt);
     for (int y = 0; y < rectangleTexture->width(); ++y) {
@@ -81,10 +89,13 @@ static void test_copy_surface_dst(skiatest::Reporter* reporter, GrContext* conte
         copySrcDesc.fWidth = rectangleTexture->width();
         copySrcDesc.fHeight = rectangleTexture->height();
         copySrcDesc.fFlags = flags;
-        sk_sp<GrTexture> src(context->textureProvider()->createTexture(
-                copySrcDesc, SkBudgeted::kYes, pixels.get(), 0));
 
-        context->copySurface(rectangleTexture, src.get());
+        sk_sp<GrSurfaceProxy> src(GrSurfaceProxy::MakeDeferred(*context->caps(),
+                                                               context->textureProvider(),
+                                                               copySrcDesc,
+                                                               SkBudgeted::kYes, pixels.get(), 0));
+        sContext->copy(src.get());
+
         test_read_pixels(reporter, context, rectangleTexture, pixels.get());
     }
 }