Cache SkPromiseImageTexture

SkPromiseImageTexture is valid as long as the metadata does not
change (e.g. side, pixel format, texture ID).

This is true for the lifetime of a SharedImage. SharedImages are reused
by renderers as part of their cc::ResourcePool. Caching saves some
work for Skia during SkiaRenderer compositing.

Change-Id: I67b6f6f138509096e2b3ec2a3cc1555e00bd23f6
Bug: 914521
Reviewed-on: https://chromium-review.googlesource.com/c/1418735
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Jonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#623960}
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
index 9bb4b7d2..469e95e 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -96,6 +96,7 @@
   base::ScopedFD gl_write_sync_fd_;
   base::ScopedFD vk_read_sync_fd_;
 
+  sk_sp<SkPromiseImageTexture> cached_promise_texture_;
   DISALLOW_COPY_AND_ASSIGN(SharedImageBackingAHB);
 };
 
@@ -161,16 +162,15 @@
 class SharedImageRepresentationSkiaGLAHB
     : public SharedImageRepresentationSkia {
  public:
-  SharedImageRepresentationSkiaGLAHB(SharedImageManager* manager,
-                                     SharedImageBacking* backing,
-                                     MemoryTypeTracker* tracker,
-                                     GLenum target,
-                                     GLuint service_id)
-      : SharedImageRepresentationSkia(manager, backing, tracker) {
-    GrBackendTexture backend_texture;
-    GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target,
-                        size(), service_id, format(), &backend_texture);
-    promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
+  SharedImageRepresentationSkiaGLAHB(
+      SharedImageManager* manager,
+      SharedImageBacking* backing,
+      sk_sp<SkPromiseImageTexture> cached_promise_image_texture,
+      MemoryTypeTracker* tracker,
+      GLenum target,
+      GLuint service_id)
+      : SharedImageRepresentationSkia(manager, backing, tracker),
+        promise_texture_(cached_promise_image_texture) {
 #if DCHECK_IS_ON()
     context_ = gl::GLContext::GetCurrent();
 #endif
@@ -538,9 +538,17 @@
   if (!GenGLTexture())
     return nullptr;
 
+  if (!cached_promise_texture_) {
+    GrBackendTexture backend_texture;
+    GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(),
+                        texture_->target(), size(), texture_->service_id(),
+                        format(), &backend_texture);
+    cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
+  }
   DCHECK(texture_);
   return std::make_unique<SharedImageRepresentationSkiaGLAHB>(
-      manager, this, tracker, texture_->target(), texture_->service_id());
+      manager, this, cached_promise_texture_, tracker, texture_->target(),
+      texture_->service_id());
 }
 
 bool SharedImageBackingAHB::GenGLTexture() {
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
index 98f46e2..63e3150 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -229,16 +229,21 @@
 
 class SharedImageRepresentationSkiaImpl : public SharedImageRepresentationSkia {
  public:
-  SharedImageRepresentationSkiaImpl(SharedImageManager* manager,
-                                    SharedImageBacking* backing,
-                                    MemoryTypeTracker* tracker,
-                                    GLenum target,
-                                    GLuint service_id)
-      : SharedImageRepresentationSkia(manager, backing, tracker) {
-    GrBackendTexture backend_texture;
-    GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target,
-                        size(), service_id, format(), &backend_texture);
-    promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
+  SharedImageRepresentationSkiaImpl(
+      SharedImageManager* manager,
+      SharedImageBacking* backing,
+      sk_sp<SkPromiseImageTexture> cached_promise_texture,
+      MemoryTypeTracker* tracker,
+      GLenum target,
+      GLuint service_id)
+      : SharedImageRepresentationSkia(manager, backing, tracker),
+        promise_texture_(cached_promise_texture) {
+    if (!promise_texture_) {
+      GrBackendTexture backend_texture;
+      GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target,
+                          size(), service_id, format(), &backend_texture);
+      promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
+    }
 #if DCHECK_IS_ON()
     context_ = gl::GLContext::GetCurrent();
 #endif
@@ -284,6 +289,8 @@
     // TODO(ericrk): Handle begin/end correctness checks.
   }
 
+  sk_sp<SkPromiseImageTexture> promise_texture() { return promise_texture_; }
+
  private:
   void CheckContext() {
 #if DCHECK_IS_ON()
@@ -389,12 +396,16 @@
   std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia(
       SharedImageManager* manager,
       MemoryTypeTracker* tracker) override {
-    return std::make_unique<SharedImageRepresentationSkiaImpl>(
-        manager, this, tracker, texture_->target(), texture_->service_id());
+    auto result = std::make_unique<SharedImageRepresentationSkiaImpl>(
+        manager, this, cached_promise_texture_, tracker, texture_->target(),
+        texture_->service_id());
+    cached_promise_texture_ = result->promise_texture();
+    return result;
   }
 
  private:
   gles2::Texture* texture_ = nullptr;
+  sk_sp<SkPromiseImageTexture> cached_promise_texture_;
 };
 
 // Implementation of SharedImageBacking that creates a GL Texture and stores it
@@ -485,13 +496,17 @@
   std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia(
       SharedImageManager* manager,
       MemoryTypeTracker* tracker) override {
-    return std::make_unique<SharedImageRepresentationSkiaImpl>(
-        manager, this, tracker, texture_passthrough_->target(),
-        texture_passthrough_->service_id());
+    auto result = std::make_unique<SharedImageRepresentationSkiaImpl>(
+        manager, this, cached_promise_texture_, tracker,
+        texture_passthrough_->target(), texture_passthrough_->service_id());
+    cached_promise_texture_ = result->promise_texture();
+    return result;
   }
 
  private:
   scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
+  sk_sp<SkPromiseImageTexture> cached_promise_texture_;
+
   bool is_cleared_ = false;
 };
 
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index e76fa8b24..cca87d4 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -82,11 +82,7 @@
         final_msaa_count, color_type, /*colorSpace=*/nullptr, &surface_props);
   }
 
-  bool GetGrBackendTexture(GrBackendTexture* gr_texture) const {
-    context_state_->need_context_state_reset = true;
-    *gr_texture = image_->getBackendTexture(/*flushPendingGrContextIO=*/true);
-    return gr_texture->isValid();
-  }
+  sk_sp<SkPromiseImageTexture> promise_texture() { return promise_texture_; }
 
  protected:
   std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia(
@@ -147,6 +143,7 @@
         image_->getBackendTexture(/*flushPendingGrContextIO=*/false);
     if (!gr_texture.isValid())
       return false;
+    promise_texture_ = SkPromiseImageTexture::Make(gr_texture);
 
     switch (gr_texture.backend()) {
       case GrBackendApi::kOpenGL: {
@@ -171,6 +168,8 @@
   RasterDecoderContextState* const context_state_;
 
   sk_sp<SkImage> image_;
+  sk_sp<SkPromiseImageTexture> promise_texture_;
+
   bool cleared_ = false;
 
   uint64_t tracing_id_ = 0;
@@ -207,12 +206,7 @@
   }
 
   sk_sp<SkPromiseImageTexture> BeginReadAccess(SkSurface* sk_surface) override {
-    if (!promise_texture_) {
-      GrBackendTexture backend_texture;
-      wrapped_sk_image()->GetGrBackendTexture(&backend_texture);
-      promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
-    }
-    return promise_texture_;
+    return wrapped_sk_image()->promise_texture();
   }
 
   void EndReadAccess() override {
@@ -225,7 +219,6 @@
   }
 
   SkSurface* write_surface_ = nullptr;
-  sk_sp<SkPromiseImageTexture> promise_texture_;
 };
 
 }  // namespace