gl_helper.h revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar// Copyright (c) 2012 The Chromium Authors. All rights reserved. 253131982d6290e3a865f400174778deaac452ff3Daniel Dunbar// Use of this source code is governed by a BSD-style license that can be 353131982d6290e3a865f400174778deaac452ff3Daniel Dunbar// found in the LICENSE file. 453131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 553131982d6290e3a865f400174778deaac452ff3Daniel Dunbar#ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 653131982d6290e3a865f400174778deaac452ff3Daniel Dunbar#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 753131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar#include "base/atomicops.h" 953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar#include "base/basictypes.h" 10674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#include "base/callback.h" 11674be02d525d4e24bc6943ed9274958c580bcfbcJakub Staszak#include "base/memory/scoped_ptr.h" 1253131982d6290e3a865f400174778deaac452ff3Daniel Dunbar#include "content/common/content_export.h" 131edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 14255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth 1553131982d6290e3a865f400174778deaac452ff3Daniel Dunbarnamespace gfx { 1653131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass Rect; 1753131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass Size; 18f21e4e9326aa3ebc78bc2770722fb5150fe7ede9Daniel Dunbar} 1953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 2053131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass SkRegion; 2153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 2253131982d6290e3a865f400174778deaac452ff3Daniel Dunbarnamespace content { 2353131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 241f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topperclass GLHelperScaling; 251f7210e808373fa92be3a2d4fa653a6f79d5088bCraig Topper 2653131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass ScopedWebGLId { 2753131982d6290e3a865f400174778deaac452ff3Daniel Dunbar public: 2853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar typedef void (WebKit::WebGraphicsContext3D::*DeleteFunc)(WebGLId); 2953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar ScopedWebGLId(WebKit::WebGraphicsContext3D* context, 3053131982d6290e3a865f400174778deaac452ff3Daniel Dunbar WebGLId id, 3153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar DeleteFunc delete_func) 321edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar : context_(context), 331edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar id_(id), 341edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar delete_func_(delete_func) { 351edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar } 361edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar 371edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar operator WebGLId() const { 381edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar return id_; 391edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar } 401edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar 4193c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger WebGLId id() const { return id_; } 4293c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger 4353131982d6290e3a865f400174778deaac452ff3Daniel Dunbar WebGLId Detach() { 4453131982d6290e3a865f400174778deaac452ff3Daniel Dunbar WebGLId id = id_; 4553131982d6290e3a865f400174778deaac452ff3Daniel Dunbar id_ = 0; 46c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko return id; 47c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko } 4853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 4953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar ~ScopedWebGLId() { 5053131982d6290e3a865f400174778deaac452ff3Daniel Dunbar if (id_ != 0) { 5153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar (context_->*delete_func_)(id_); 5253131982d6290e3a865f400174778deaac452ff3Daniel Dunbar } 5353131982d6290e3a865f400174778deaac452ff3Daniel Dunbar } 5453131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 5553131982d6290e3a865f400174778deaac452ff3Daniel Dunbar private: 5653131982d6290e3a865f400174778deaac452ff3Daniel Dunbar WebKit::WebGraphicsContext3D* context_; 574e82bbb745160f19d76b9b5de5b93ebe224e1acfDaniel Dunbar WebGLId id_; 5853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar DeleteFunc delete_func_; 59f8cd708f14a7a172d51899b68809510ae0c4c4c8Joerg Sonnenberger 6053131982d6290e3a865f400174778deaac452ff3Daniel Dunbar DISALLOW_COPY_AND_ASSIGN(ScopedWebGLId); 6153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar}; 6253131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 6353131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass ScopedBuffer : public ScopedWebGLId { 6453131982d6290e3a865f400174778deaac452ff3Daniel Dunbar public: 65f21e4e9326aa3ebc78bc2770722fb5150fe7ede9Daniel Dunbar ScopedBuffer(WebKit::WebGraphicsContext3D* context, 66f21e4e9326aa3ebc78bc2770722fb5150fe7ede9Daniel Dunbar WebGLId id) 67f21e4e9326aa3ebc78bc2770722fb5150fe7ede9Daniel Dunbar : ScopedWebGLId(context, 6853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar id, 6953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar &WebKit::WebGraphicsContext3D::deleteBuffer) {} 7053131982d6290e3a865f400174778deaac452ff3Daniel Dunbar}; 7153131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 7253131982d6290e3a865f400174778deaac452ff3Daniel Dunbarclass ScopedFramebuffer : public ScopedWebGLId { 7393c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger public: 7493c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger ScopedFramebuffer(WebKit::WebGraphicsContext3D* context, 7553131982d6290e3a865f400174778deaac452ff3Daniel Dunbar WebGLId id) 7653131982d6290e3a865f400174778deaac452ff3Daniel Dunbar : ScopedWebGLId(context, 7753131982d6290e3a865f400174778deaac452ff3Daniel Dunbar id, 7853131982d6290e3a865f400174778deaac452ff3Daniel Dunbar &WebKit::WebGraphicsContext3D::deleteFramebuffer) {} 7953131982d6290e3a865f400174778deaac452ff3Daniel Dunbar}; 8053131982d6290e3a865f400174778deaac452ff3Daniel Dunbar 81class ScopedProgram : public ScopedWebGLId { 82 public: 83 ScopedProgram(WebKit::WebGraphicsContext3D* context, 84 WebGLId id) 85 : ScopedWebGLId(context, 86 id, 87 &WebKit::WebGraphicsContext3D::deleteProgram) {} 88}; 89 90class ScopedShader : public ScopedWebGLId { 91 public: 92 ScopedShader(WebKit::WebGraphicsContext3D* context, 93 WebGLId id) 94 : ScopedWebGLId(context, 95 id, 96 &WebKit::WebGraphicsContext3D::deleteShader) {} 97}; 98 99class ScopedTexture : public ScopedWebGLId { 100 public: 101 ScopedTexture(WebKit::WebGraphicsContext3D* context, 102 WebGLId id) 103 : ScopedWebGLId(context, 104 id, 105 &WebKit::WebGraphicsContext3D::deleteTexture) {} 106}; 107 108template <WebKit::WGC3Denum target> 109class ScopedBinder { 110 public: 111 typedef void (WebKit::WebGraphicsContext3D::*BindFunc)(WebKit::WGC3Denum, 112 WebGLId); 113 ScopedBinder(WebKit::WebGraphicsContext3D* context, 114 WebGLId id, 115 BindFunc bind_func) 116 : context_(context), 117 bind_func_(bind_func) { 118 (context_->*bind_func_)(target, id); 119 } 120 121 virtual ~ScopedBinder() { 122 (context_->*bind_func_)(target, 0); 123 } 124 125 private: 126 WebKit::WebGraphicsContext3D* context_; 127 BindFunc bind_func_; 128 129 DISALLOW_COPY_AND_ASSIGN(ScopedBinder); 130}; 131 132template <WebKit::WGC3Denum target> 133class ScopedBufferBinder : ScopedBinder<target> { 134 public: 135 ScopedBufferBinder(WebKit::WebGraphicsContext3D* context, 136 WebGLId id) 137 : ScopedBinder<target>( 138 context, 139 id, 140 &WebKit::WebGraphicsContext3D::bindBuffer) {} 141}; 142 143template <WebKit::WGC3Denum target> 144class ScopedFramebufferBinder : ScopedBinder<target> { 145 public: 146 ScopedFramebufferBinder(WebKit::WebGraphicsContext3D* context, 147 WebGLId id) 148 : ScopedBinder<target>( 149 context, 150 id, 151 &WebKit::WebGraphicsContext3D::bindFramebuffer) {} 152}; 153 154template <WebKit::WGC3Denum target> 155class ScopedTextureBinder : ScopedBinder<target> { 156 public: 157 ScopedTextureBinder(WebKit::WebGraphicsContext3D* context, 158 WebGLId id) 159 : ScopedBinder<target>( 160 context, 161 id, 162 &WebKit::WebGraphicsContext3D::bindTexture) {} 163}; 164 165class ScopedFlush { 166 public: 167 explicit ScopedFlush(WebKit::WebGraphicsContext3D* context) 168 : context_(context) { 169 } 170 171 ~ScopedFlush() { 172 context_->flush(); 173 } 174 175 private: 176 WebKit::WebGraphicsContext3D* context_; 177 178 DISALLOW_COPY_AND_ASSIGN(ScopedFlush); 179}; 180 181// Provides higher level operations on top of the WebKit::WebGraphicsContext3D 182// interfaces. 183class CONTENT_EXPORT GLHelper { 184 public: 185 explicit GLHelper(WebKit::WebGraphicsContext3D* context); 186 ~GLHelper(); 187 188 enum ScalerQuality { 189 // Bilinear single pass, fastest possible. 190 SCALER_QUALITY_FAST = 1, 191 192 // Bilinear upscale + N * 50% bilinear downscales. 193 // This is still fast enough for most purposes and 194 // Image quality is nearly as good as the BEST option. 195 SCALER_QUALITY_GOOD = 2, 196 197 // Bicubic upscale + N * 50% bicubic downscales. 198 // Produces very good quality scaled images, but it's 199 // 2-8x slower than the "GOOD" quality, so it's not always 200 // worth it. 201 SCALER_QUALITY_BEST = 3, 202 }; 203 204 205 // Copies the block of pixels specified with |src_subrect| from |src_texture|, 206 // scales it to |dst_size|, and writes it into |out|. 207 // |src_size| is the size of |src_texture|. The result is of format GL_BGRA 208 // and is potentially flipped vertically to make it a correct image 209 // representation. |callback| is invoked with the copy result when the copy 210 // operation has completed. 211 // Note that the src_texture will have the min/mag filter set to GL_LINEAR 212 // and wrap_s/t set to CLAMP_TO_EDGE in this call. 213 void CropScaleReadbackAndCleanTexture( 214 WebKit::WebGLId src_texture, 215 const gfx::Size& src_size, 216 const gfx::Rect& src_subrect, 217 const gfx::Size& dst_size, 218 unsigned char* out, 219 const base::Callback<void(bool)>& callback); 220 221 // Copies the texture data out of |texture| into |out|. |size| is the 222 // size of the texture. No post processing is applied to the pixels. The 223 // texture is assumed to have a format of GL_RGBA with a pixel type of 224 // GL_UNSIGNED_BYTE. This is a blocking call that calls glReadPixels on this 225 // current context. 226 void ReadbackTextureSync(WebKit::WebGLId texture, 227 const gfx::Rect& src_rect, 228 unsigned char* out); 229 230 // Creates a copy of the specified texture. |size| is the size of the texture. 231 // Note that the src_texture will have the min/mag filter set to GL_LINEAR 232 // and wrap_s/t set to CLAMP_TO_EDGE in this call. 233 WebKit::WebGLId CopyTexture(WebKit::WebGLId texture, 234 const gfx::Size& size); 235 236 // Creates a scaled copy of the specified texture. |src_size| is the size of 237 // the texture and |dst_size| is the size of the resulting copy. 238 // Note that the src_texture will have the min/mag filter set to GL_LINEAR 239 // and wrap_s/t set to CLAMP_TO_EDGE in this call. 240 WebKit::WebGLId CopyAndScaleTexture( 241 WebKit::WebGLId texture, 242 const gfx::Size& src_size, 243 const gfx::Size& dst_size, 244 bool vertically_flip_texture, 245 ScalerQuality quality); 246 247 // Returns the shader compiled from the source. 248 WebKit::WebGLId CompileShaderFromSource(const WebKit::WGC3Dchar* source, 249 WebKit::WGC3Denum type); 250 251 // Copies all pixels from |previous_texture| into |texture| that are 252 // inside the region covered by |old_damage| but not part of |new_damage|. 253 void CopySubBufferDamage(WebKit::WebGLId texture, 254 WebKit::WebGLId previous_texture, 255 const SkRegion& new_damage, 256 const SkRegion& old_damage); 257 258 // A scaler will cache all intermediate textures and programs 259 // needed to scale from a specified size to a destination size. 260 // If the source or destination sizes changes, you must create 261 // a new scaler. 262 class CONTENT_EXPORT ScalerInterface { 263 public: 264 ScalerInterface() {} 265 virtual ~ScalerInterface() {} 266 267 // Note that the src_texture will have the min/mag filter set to GL_LINEAR 268 // and wrap_s/t set to CLAMP_TO_EDGE in this call. 269 virtual void Scale(WebKit::WebGLId source_texture, 270 WebKit::WebGLId dest_texture) = 0; 271 virtual const gfx::Size& SrcSize() = 0; 272 virtual const gfx::Rect& SrcSubrect() = 0; 273 virtual const gfx::Size& DstSize() = 0; 274 }; 275 276 // Note that the quality may be adjusted down if texture 277 // allocations fail or hardware doesn't support the requtested 278 // quality. Note that ScalerQuality enum is arranged in 279 // numerical order for simplicity. 280 ScalerInterface* CreateScaler(ScalerQuality quality, 281 const gfx::Size& src_size, 282 const gfx::Rect& src_subrect, 283 const gfx::Size& dst_size, 284 bool vertically_flip_texture, 285 bool swizzle); 286 287 protected: 288 class CopyTextureToImpl; 289 290 // Creates |copy_texture_to_impl_| if NULL. 291 void InitCopyTextToImpl(); 292 // Creates |scaler_impl_| if NULL. 293 void InitScalerImpl(); 294 295 WebKit::WebGraphicsContext3D* context_; 296 scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_; 297 scoped_ptr<GLHelperScaling> scaler_impl_; 298 299 DISALLOW_COPY_AND_ASSIGN(GLHelper); 300}; 301 302} // namespace content 303 304#endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_ 305