| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 #ifndef COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_H_ |  | 
| 6 #define COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_H_ |  | 
| 7 |  | 
| 8 #include <memory> |  | 
| 9 |  | 
| 10 #include "base/atomicops.h" |  | 
| 11 #include "base/callback.h" |  | 
| 12 #include "base/macros.h" |  | 
| 13 #include "components/display_compositor/display_compositor_export.h" |  | 
| 14 #include "gpu/command_buffer/client/gles2_interface.h" |  | 
| 15 #include "gpu/command_buffer/common/mailbox_holder.h" |  | 
| 16 #include "third_party/skia/include/core/SkBitmap.h" |  | 
| 17 |  | 
| 18 namespace gfx { |  | 
| 19 class Point; |  | 
| 20 class Rect; |  | 
| 21 class Size; |  | 
| 22 } |  | 
| 23 |  | 
| 24 namespace gpu { |  | 
| 25 class ContextSupport; |  | 
| 26 struct Mailbox; |  | 
| 27 } |  | 
| 28 |  | 
| 29 class SkRegion; |  | 
| 30 |  | 
| 31 namespace display_compositor { |  | 
| 32 |  | 
| 33 class GLHelperScaling; |  | 
| 34 |  | 
| 35 class DISPLAY_COMPOSITOR_EXPORT ScopedGLuint { |  | 
| 36  public: |  | 
| 37   typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids); |  | 
| 38   typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n, |  | 
| 39                                                          const GLuint* ids); |  | 
| 40   ScopedGLuint(gpu::gles2::GLES2Interface* gl, |  | 
| 41                GenFunc gen_func, |  | 
| 42                DeleteFunc delete_func) |  | 
| 43       : gl_(gl), id_(0u), delete_func_(delete_func) { |  | 
| 44     (gl_->*gen_func)(1, &id_); |  | 
| 45   } |  | 
| 46 |  | 
| 47   operator GLuint() const { return id_; } |  | 
| 48 |  | 
| 49   GLuint id() const { return id_; } |  | 
| 50 |  | 
| 51   ~ScopedGLuint() { |  | 
| 52     if (id_ != 0) { |  | 
| 53       (gl_->*delete_func_)(1, &id_); |  | 
| 54     } |  | 
| 55   } |  | 
| 56 |  | 
| 57  private: |  | 
| 58   gpu::gles2::GLES2Interface* gl_; |  | 
| 59   GLuint id_; |  | 
| 60   DeleteFunc delete_func_; |  | 
| 61 |  | 
| 62   DISALLOW_COPY_AND_ASSIGN(ScopedGLuint); |  | 
| 63 }; |  | 
| 64 |  | 
| 65 class ScopedBuffer : public ScopedGLuint { |  | 
| 66  public: |  | 
| 67   explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl) |  | 
| 68       : ScopedGLuint(gl, |  | 
| 69                      &gpu::gles2::GLES2Interface::GenBuffers, |  | 
| 70                      &gpu::gles2::GLES2Interface::DeleteBuffers) {} |  | 
| 71 }; |  | 
| 72 |  | 
| 73 class ScopedFramebuffer : public ScopedGLuint { |  | 
| 74  public: |  | 
| 75   explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl) |  | 
| 76       : ScopedGLuint(gl, |  | 
| 77                      &gpu::gles2::GLES2Interface::GenFramebuffers, |  | 
| 78                      &gpu::gles2::GLES2Interface::DeleteFramebuffers) {} |  | 
| 79 }; |  | 
| 80 |  | 
| 81 class ScopedTexture : public ScopedGLuint { |  | 
| 82  public: |  | 
| 83   explicit ScopedTexture(gpu::gles2::GLES2Interface* gl) |  | 
| 84       : ScopedGLuint(gl, |  | 
| 85                      &gpu::gles2::GLES2Interface::GenTextures, |  | 
| 86                      &gpu::gles2::GLES2Interface::DeleteTextures) {} |  | 
| 87 }; |  | 
| 88 |  | 
| 89 template <GLenum Target> |  | 
| 90 class ScopedBinder { |  | 
| 91  public: |  | 
| 92   typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target, |  | 
| 93                                                        GLuint id); |  | 
| 94   ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func) |  | 
| 95       : gl_(gl), bind_func_(bind_func) { |  | 
| 96     (gl_->*bind_func_)(Target, id); |  | 
| 97   } |  | 
| 98 |  | 
| 99   virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); } |  | 
| 100 |  | 
| 101  private: |  | 
| 102   gpu::gles2::GLES2Interface* gl_; |  | 
| 103   BindFunc bind_func_; |  | 
| 104 |  | 
| 105   DISALLOW_COPY_AND_ASSIGN(ScopedBinder); |  | 
| 106 }; |  | 
| 107 |  | 
| 108 template <GLenum Target> |  | 
| 109 class ScopedBufferBinder : ScopedBinder<Target> { |  | 
| 110  public: |  | 
| 111   ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id) |  | 
| 112       : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {} |  | 
| 113 }; |  | 
| 114 |  | 
| 115 template <GLenum Target> |  | 
| 116 class ScopedFramebufferBinder : ScopedBinder<Target> { |  | 
| 117  public: |  | 
| 118   ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id) |  | 
| 119       : ScopedBinder<Target>(gl, |  | 
| 120                              id, |  | 
| 121                              &gpu::gles2::GLES2Interface::BindFramebuffer) {} |  | 
| 122 }; |  | 
| 123 |  | 
| 124 template <GLenum Target> |  | 
| 125 class ScopedTextureBinder : ScopedBinder<Target> { |  | 
| 126  public: |  | 
| 127   ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id) |  | 
| 128       : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) { |  | 
| 129   } |  | 
| 130 }; |  | 
| 131 |  | 
| 132 class ReadbackYUVInterface; |  | 
| 133 class GLHelperReadbackSupport; |  | 
| 134 |  | 
| 135 // Provides higher level operations on top of the gpu::gles2::GLES2Interface |  | 
| 136 // interfaces. |  | 
| 137 class DISPLAY_COMPOSITOR_EXPORT GLHelper { |  | 
| 138  public: |  | 
| 139   GLHelper(gpu::gles2::GLES2Interface* gl, |  | 
| 140            gpu::ContextSupport* context_support); |  | 
| 141   ~GLHelper(); |  | 
| 142 |  | 
| 143   enum ScalerQuality { |  | 
| 144     // Bilinear single pass, fastest possible. |  | 
| 145     SCALER_QUALITY_FAST = 1, |  | 
| 146 |  | 
| 147     // Bilinear upscale + N * 50% bilinear downscales. |  | 
| 148     // This is still fast enough for most purposes and |  | 
| 149     // Image quality is nearly as good as the BEST option. |  | 
| 150     SCALER_QUALITY_GOOD = 2, |  | 
| 151 |  | 
| 152     // Bicubic upscale + N * 50% bicubic downscales. |  | 
| 153     // Produces very good quality scaled images, but it's |  | 
| 154     // 2-8x slower than the "GOOD" quality, so it's not always |  | 
| 155     // worth it. |  | 
| 156     SCALER_QUALITY_BEST = 3, |  | 
| 157   }; |  | 
| 158 |  | 
| 159   // Copies the block of pixels specified with |src_subrect| from |src_texture|, |  | 
| 160   // scales it to |dst_size|, and writes it into |out|. |  | 
| 161   // |src_size| is the size of |src_texture|. The result is in |out_color_type| |  | 
| 162   // format and is potentially flipped vertically to make it a correct image |  | 
| 163   // representation.  |callback| is invoked with the copy result when the copy |  | 
| 164   // operation has completed. |  | 
| 165   // Note that the src_texture will have the min/mag filter set to GL_LINEAR |  | 
| 166   // and wrap_s/t set to CLAMP_TO_EDGE in this call. |  | 
| 167   void CropScaleReadbackAndCleanTexture( |  | 
| 168       GLuint src_texture, |  | 
| 169       const gfx::Size& src_size, |  | 
| 170       const gfx::Rect& src_subrect, |  | 
| 171       const gfx::Size& dst_size, |  | 
| 172       unsigned char* out, |  | 
| 173       const SkColorType out_color_type, |  | 
| 174       const base::Callback<void(bool)>& callback, |  | 
| 175       GLHelper::ScalerQuality quality); |  | 
| 176 |  | 
| 177   // Copies the block of pixels specified with |src_subrect| from |src_mailbox|, |  | 
| 178   // scales it to |dst_size|, and writes it into |out|. |  | 
| 179   // |src_size| is the size of |src_mailbox|. The result is in |out_color_type| |  | 
| 180   // format and is potentially flipped vertically to make it a correct image |  | 
| 181   // representation.  |callback| is invoked with the copy result when the copy |  | 
| 182   // operation has completed. |  | 
| 183   // Note that the texture bound to src_mailbox will have the min/mag filter set |  | 
| 184   // to GL_LINEAR and wrap_s/t set to CLAMP_TO_EDGE in this call. src_mailbox is |  | 
| 185   // assumed to be GL_TEXTURE_2D. |  | 
| 186   void CropScaleReadbackAndCleanMailbox( |  | 
| 187       const gpu::Mailbox& src_mailbox, |  | 
| 188       const gpu::SyncToken& sync_token, |  | 
| 189       const gfx::Size& src_size, |  | 
| 190       const gfx::Rect& src_subrect, |  | 
| 191       const gfx::Size& dst_size, |  | 
| 192       unsigned char* out, |  | 
| 193       const SkColorType out_color_type, |  | 
| 194       const base::Callback<void(bool)>& callback, |  | 
| 195       GLHelper::ScalerQuality quality); |  | 
| 196 |  | 
| 197   // Copies the texture data out of |texture| into |out|.  |size| is the |  | 
| 198   // size of the texture.  No post processing is applied to the pixels.  The |  | 
| 199   // texture is assumed to have a format of GL_RGBA with a pixel type of |  | 
| 200   // GL_UNSIGNED_BYTE.  This is a blocking call that calls glReadPixels on the |  | 
| 201   // current OpenGL context. |  | 
| 202   void ReadbackTextureSync(GLuint texture, |  | 
| 203                            const gfx::Rect& src_rect, |  | 
| 204                            unsigned char* out, |  | 
| 205                            SkColorType format); |  | 
| 206 |  | 
| 207   void ReadbackTextureAsync(GLuint texture, |  | 
| 208                             const gfx::Size& dst_size, |  | 
| 209                             unsigned char* out, |  | 
| 210                             SkColorType color_type, |  | 
| 211                             const base::Callback<void(bool)>& callback); |  | 
| 212 |  | 
| 213   // Creates a copy of the specified texture. |size| is the size of the texture. |  | 
| 214   // Note that the src_texture will have the min/mag filter set to GL_LINEAR |  | 
| 215   // and wrap_s/t set to CLAMP_TO_EDGE in this call. |  | 
| 216   GLuint CopyTexture(GLuint texture, const gfx::Size& size); |  | 
| 217 |  | 
| 218   // Creates a scaled copy of the specified texture. |src_size| is the size of |  | 
| 219   // the texture and |dst_size| is the size of the resulting copy. |  | 
| 220   // Note that the src_texture will have the min/mag filter set to GL_LINEAR |  | 
| 221   // and wrap_s/t set to CLAMP_TO_EDGE in this call. |  | 
| 222   GLuint CopyAndScaleTexture(GLuint texture, |  | 
| 223                              const gfx::Size& src_size, |  | 
| 224                              const gfx::Size& dst_size, |  | 
| 225                              bool vertically_flip_texture, |  | 
| 226                              ScalerQuality quality); |  | 
| 227 |  | 
| 228   // Returns the shader compiled from the source. |  | 
| 229   GLuint CompileShaderFromSource(const GLchar* source, GLenum type); |  | 
| 230 |  | 
| 231   // Copies all pixels from |previous_texture| into |texture| that are |  | 
| 232   // inside the region covered by |old_damage| but not part of |new_damage|. |  | 
| 233   void CopySubBufferDamage(GLenum target, |  | 
| 234                            GLuint texture, |  | 
| 235                            GLuint previous_texture, |  | 
| 236                            const SkRegion& new_damage, |  | 
| 237                            const SkRegion& old_damage); |  | 
| 238 |  | 
| 239   // Simply creates a texture. |  | 
| 240   GLuint CreateTexture(); |  | 
| 241   // Deletes a texture. |  | 
| 242   void DeleteTexture(GLuint texture_id); |  | 
| 243 |  | 
| 244   // Inserts a fence sync, flushes, and generates a sync token. |  | 
| 245   void GenerateSyncToken(gpu::SyncToken* sync_token); |  | 
| 246 |  | 
| 247   // Wait for the sync token before executing further GL commands. |  | 
| 248   void WaitSyncToken(const gpu::SyncToken& sync_token); |  | 
| 249 |  | 
| 250   // Creates a mailbox holder that is attached to the given texture id, with a |  | 
| 251   // sync point to wait on before using the mailbox. Returns a holder with an |  | 
| 252   // empty mailbox on failure. |  | 
| 253   // Note the texture is assumed to be GL_TEXTURE_2D. |  | 
| 254   gpu::MailboxHolder ProduceMailboxHolderFromTexture(GLuint texture_id); |  | 
| 255 |  | 
| 256   // Creates a texture and consumes a mailbox into it. Returns 0 on failure. |  | 
| 257   // Note the mailbox is assumed to be GL_TEXTURE_2D. |  | 
| 258   GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, |  | 
| 259                                  const gpu::SyncToken& sync_token); |  | 
| 260 |  | 
| 261   // Resizes the texture's size to |size|. |  | 
| 262   void ResizeTexture(GLuint texture, const gfx::Size& size); |  | 
| 263 |  | 
| 264   // Copies the framebuffer data given in |rect| to |texture|. |  | 
| 265   void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect); |  | 
| 266 |  | 
| 267   // Copies the all framebuffer data to |texture|. |size| specifies the |  | 
| 268   // size of the framebuffer. |  | 
| 269   void CopyTextureFullImage(GLuint texture, const gfx::Size& size); |  | 
| 270 |  | 
| 271   // Flushes GL commands. |  | 
| 272   void Flush(); |  | 
| 273 |  | 
| 274   // Force commands in the current command buffer to be executed before commands |  | 
| 275   // in other command buffers from the same process (ie channel to the GPU |  | 
| 276   // process). |  | 
| 277   void InsertOrderingBarrier(); |  | 
| 278 |  | 
| 279   // A scaler will cache all intermediate textures and programs |  | 
| 280   // needed to scale from a specified size to a destination size. |  | 
| 281   // If the source or destination sizes changes, you must create |  | 
| 282   // a new scaler. |  | 
| 283   class DISPLAY_COMPOSITOR_EXPORT ScalerInterface { |  | 
| 284    public: |  | 
| 285     ScalerInterface() {} |  | 
| 286     virtual ~ScalerInterface() {} |  | 
| 287 |  | 
| 288     // Note that the src_texture will have the min/mag filter set to GL_LINEAR |  | 
| 289     // and wrap_s/t set to CLAMP_TO_EDGE in this call. |  | 
| 290     virtual void Scale(GLuint source_texture, GLuint dest_texture) = 0; |  | 
| 291     virtual const gfx::Size& SrcSize() = 0; |  | 
| 292     virtual const gfx::Rect& SrcSubrect() = 0; |  | 
| 293     virtual const gfx::Size& DstSize() = 0; |  | 
| 294   }; |  | 
| 295 |  | 
| 296   // Note that the quality may be adjusted down if texture |  | 
| 297   // allocations fail or hardware doesn't support the requtested |  | 
| 298   // quality. Note that ScalerQuality enum is arranged in |  | 
| 299   // numerical order for simplicity. |  | 
| 300   ScalerInterface* CreateScaler(ScalerQuality quality, |  | 
| 301                                 const gfx::Size& src_size, |  | 
| 302                                 const gfx::Rect& src_subrect, |  | 
| 303                                 const gfx::Size& dst_size, |  | 
| 304                                 bool vertically_flip_texture, |  | 
| 305                                 bool swizzle); |  | 
| 306 |  | 
| 307   // Create a readback pipeline that will scale a subsection of the source |  | 
| 308   // texture, then convert it to YUV422 planar form and then read back that. |  | 
| 309   // This reduces the amount of memory read from GPU to CPU memory by a factor |  | 
| 310   // 2.6, which can be quite handy since readbacks have very limited speed |  | 
| 311   // on some platforms. All values in |dst_size| must be a multiple of two. If |  | 
| 312   // |use_mrt| is true, the pipeline will try to optimize the YUV conversion |  | 
| 313   // using the multi-render-target extension. |use_mrt| should only be set to |  | 
| 314   // false for testing. |  | 
| 315   ReadbackYUVInterface* CreateReadbackPipelineYUV(ScalerQuality quality, |  | 
| 316                                                   const gfx::Size& src_size, |  | 
| 317                                                   const gfx::Rect& src_subrect, |  | 
| 318                                                   const gfx::Size& dst_size, |  | 
| 319                                                   bool flip_vertically, |  | 
| 320                                                   bool use_mrt); |  | 
| 321 |  | 
| 322   // Returns the maximum number of draw buffers available, |  | 
| 323   // 0 if GL_EXT_draw_buffers is not available. |  | 
| 324   GLint MaxDrawBuffers(); |  | 
| 325 |  | 
| 326   // Checks whether the readbback is supported for texture with the |  | 
| 327   // matching config. This doesnt check for cross format readbacks. |  | 
| 328   bool IsReadbackConfigSupported(SkColorType texture_format); |  | 
| 329 |  | 
| 330  protected: |  | 
| 331   class CopyTextureToImpl; |  | 
| 332 |  | 
| 333   // Creates |copy_texture_to_impl_| if NULL. |  | 
| 334   void InitCopyTextToImpl(); |  | 
| 335   // Creates |scaler_impl_| if NULL. |  | 
| 336   void InitScalerImpl(); |  | 
| 337 |  | 
| 338   enum ReadbackSwizzle { kSwizzleNone = 0, kSwizzleBGRA }; |  | 
| 339 |  | 
| 340   gpu::gles2::GLES2Interface* gl_; |  | 
| 341   gpu::ContextSupport* context_support_; |  | 
| 342   std::unique_ptr<CopyTextureToImpl> copy_texture_to_impl_; |  | 
| 343   std::unique_ptr<GLHelperScaling> scaler_impl_; |  | 
| 344   std::unique_ptr<GLHelperReadbackSupport> readback_support_; |  | 
| 345 |  | 
| 346   DISALLOW_COPY_AND_ASSIGN(GLHelper); |  | 
| 347 }; |  | 
| 348 |  | 
| 349 // Similar to a ScalerInterface, a yuv readback pipeline will |  | 
| 350 // cache a scaler and all intermediate textures and frame buffers |  | 
| 351 // needed to scale, crop, letterbox and read back a texture from |  | 
| 352 // the GPU into CPU-accessible RAM. A single readback pipeline |  | 
| 353 // can handle multiple outstanding readbacks at the same time, but |  | 
| 354 // if the source or destination sizes change, you'll need to create |  | 
| 355 // a new readback pipeline. |  | 
| 356 class DISPLAY_COMPOSITOR_EXPORT ReadbackYUVInterface { |  | 
| 357  public: |  | 
| 358   ReadbackYUVInterface() {} |  | 
| 359   virtual ~ReadbackYUVInterface() {} |  | 
| 360 |  | 
| 361   // Note that |target| must use YV12 format.  |paste_location| specifies where |  | 
| 362   // the captured pixels that are read back will be placed in the video frame. |  | 
| 363   // The region defined by the |paste_location| and the |dst_size| specified in |  | 
| 364   // the call to CreateReadbackPipelineYUV() must be fully contained within |  | 
| 365   // |target->visible_rect()|. |  | 
| 366   virtual void ReadbackYUV(const gpu::Mailbox& mailbox, |  | 
| 367                            const gpu::SyncToken& sync_token, |  | 
| 368                            const gfx::Rect& target_visible_rect, |  | 
| 369                            int y_plane_row_stride_bytes, |  | 
| 370                            unsigned char* y_plane_data, |  | 
| 371                            int u_plane_row_stride_bytes, |  | 
| 372                            unsigned char* u_plane_data, |  | 
| 373                            int v_plane_row_stride_bytes, |  | 
| 374                            unsigned char* v_plane_data, |  | 
| 375                            const gfx::Point& paste_location, |  | 
| 376                            const base::Callback<void(bool)>& callback) = 0; |  | 
| 377   virtual GLHelper::ScalerInterface* scaler() = 0; |  | 
| 378 }; |  | 
| 379 |  | 
| 380 }  // namespace display_compositor |  | 
| 381 |  | 
| 382 #endif  // COMPONENTS_DISPLAY_COMPOSITOR_GL_HELPER_H_ |  | 
| OLD | NEW | 
|---|