Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/client/gl_helper.h" | 5 #include "content/common/gpu/client/gl_helper.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | |
| 10 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
| 15 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
| 16 #include "base/threading/thread.h" | 17 #include "base/threading/thread.h" |
| 17 #include "base/threading/thread_restrictions.h" | 18 #include "base/threading/thread_restrictions.h" |
| 19 #include "base/time.h" | |
| 18 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" | 20 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" |
| 19 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | 21 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" |
| 20 #include "third_party/skia/include/core/SkRegion.h" | 22 #include "third_party/skia/include/core/SkRegion.h" |
| 21 #include "ui/gfx/rect.h" | 23 #include "ui/gfx/rect.h" |
| 22 #include "ui/gfx/size.h" | 24 #include "ui/gfx/size.h" |
| 23 #include "ui/gl/gl_bindings.h" | 25 #include "ui/gl/gl_bindings.h" |
| 24 | 26 |
| 25 using WebKit::WebGLId; | 27 using WebKit::WebGLId; |
| 26 using WebKit::WebGraphicsContext3D; | 28 using WebKit::WebGraphicsContext3D; |
| 27 | 29 |
| 28 namespace { | 30 namespace { |
| 29 | 31 |
| 30 const char kGLHelperThreadName[] = "GLHelperThread"; | |
| 31 | |
| 32 class GLHelperThread : public base::Thread { | |
| 33 public: | |
| 34 GLHelperThread() : base::Thread(kGLHelperThreadName) { | |
| 35 Start(); | |
| 36 } | |
| 37 virtual ~GLHelperThread() { | |
| 38 Stop(); | |
| 39 } | |
| 40 | |
| 41 private: | |
| 42 DISALLOW_COPY_AND_ASSIGN(GLHelperThread); | |
| 43 }; | |
| 44 | |
| 45 base::LazyInstance<GLHelperThread> g_gl_helper_thread = | |
| 46 LAZY_INSTANCE_INITIALIZER; | |
| 47 | |
| 48 class ScopedWebGLId { | 32 class ScopedWebGLId { |
| 49 public: | 33 public: |
| 50 typedef void (WebGraphicsContext3D::*DeleteFunc)(WebGLId); | 34 typedef void (WebGraphicsContext3D::*DeleteFunc)(WebGLId); |
| 51 ScopedWebGLId(WebGraphicsContext3D* context, | 35 ScopedWebGLId(WebGraphicsContext3D* context, |
| 52 WebGLId id, | 36 WebGLId id, |
| 53 DeleteFunc delete_func) | 37 DeleteFunc delete_func) |
| 54 : context_(context), | 38 : context_(context), |
| 55 id_(id), | 39 id_(id), |
| 56 delete_func_(delete_func) { | 40 delete_func_(delete_func) { |
| 57 } | 41 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 | 76 |
| 93 class ScopedFramebuffer : public ScopedWebGLId { | 77 class ScopedFramebuffer : public ScopedWebGLId { |
| 94 public: | 78 public: |
| 95 ScopedFramebuffer(WebGraphicsContext3D* context, | 79 ScopedFramebuffer(WebGraphicsContext3D* context, |
| 96 WebGLId id) | 80 WebGLId id) |
| 97 : ScopedWebGLId(context, | 81 : ScopedWebGLId(context, |
| 98 id, | 82 id, |
| 99 &WebGraphicsContext3D::deleteFramebuffer) {} | 83 &WebGraphicsContext3D::deleteFramebuffer) {} |
| 100 }; | 84 }; |
| 101 | 85 |
| 102 class ScopedRenderbuffer : public ScopedWebGLId { | |
| 103 public: | |
| 104 ScopedRenderbuffer(WebGraphicsContext3D* context, | |
| 105 WebGLId id) | |
| 106 : ScopedWebGLId(context, | |
| 107 id, | |
| 108 &WebGraphicsContext3D::deleteRenderbuffer) {} | |
| 109 }; | |
| 110 | |
| 111 class ScopedProgram : public ScopedWebGLId { | 86 class ScopedProgram : public ScopedWebGLId { |
| 112 public: | 87 public: |
| 113 ScopedProgram(WebGraphicsContext3D* context, | 88 ScopedProgram(WebGraphicsContext3D* context, |
| 114 WebGLId id) | 89 WebGLId id) |
| 115 : ScopedWebGLId(context, | 90 : ScopedWebGLId(context, |
| 116 id, | 91 id, |
| 117 &WebGraphicsContext3D::deleteProgram) {} | 92 &WebGraphicsContext3D::deleteProgram) {} |
| 118 }; | 93 }; |
| 119 | 94 |
| 120 class ScopedShader : public ScopedWebGLId { | 95 class ScopedShader : public ScopedWebGLId { |
| 121 public: | 96 public: |
| 122 ScopedShader(WebGraphicsContext3D* context, | 97 ScopedShader(WebGraphicsContext3D* context, |
| 123 WebGLId id) | 98 WebGLId id) |
| 124 : ScopedWebGLId(context, | 99 : ScopedWebGLId(context, |
| 125 id, | 100 id, |
| 126 &WebGraphicsContext3D::deleteShader) {} | 101 &WebGraphicsContext3D::deleteShader) {} |
| 127 }; | 102 }; |
| 128 | 103 |
| 129 class ScopedTexture : public ScopedWebGLId { | 104 class ScopedTexture : public ScopedWebGLId { |
| 130 public: | 105 public: |
| 131 ScopedTexture(WebGraphicsContext3D* context, | 106 ScopedTexture(WebGraphicsContext3D* context, |
| 132 WebGLId id) | 107 WebGLId id) |
| 133 : ScopedWebGLId(context, | 108 : ScopedWebGLId(context, |
| 134 id, | 109 id, |
| 135 &WebGraphicsContext3D::deleteTexture) {} | 110 &WebGraphicsContext3D::deleteTexture) {} |
| 136 }; | 111 }; |
| 137 | 112 |
| 138 template <WebKit::WGC3Denum target> | 113 template <WebKit::WGC3Denum target, |
| 114 WebKit::WGC3Denum target_binding> | |
| 139 class ScopedBinder { | 115 class ScopedBinder { |
| 140 public: | 116 public: |
| 141 typedef void (WebGraphicsContext3D::*BindFunc)(WebKit::WGC3Denum, | 117 typedef void (WebGraphicsContext3D::*BindFunc)(WebKit::WGC3Denum, |
| 142 WebGLId); | 118 WebGLId); |
| 143 ScopedBinder(WebGraphicsContext3D* context, | 119 ScopedBinder(WebGraphicsContext3D* context, |
| 144 WebGLId id, | 120 WebGLId id, |
| 145 BindFunc bind_func) | 121 BindFunc bind_func) |
| 146 : context_(context), | 122 : context_(context), |
| 147 id_(id), | |
| 148 bind_func_(bind_func) { | 123 bind_func_(bind_func) { |
| 149 (context_->*bind_func_)(target, id_); | 124 context_->getIntegerv(target_binding, &prev_id_); |
|
greggman
2013/03/20 00:59:12
I know al said it was okay to call getInteger but
| |
| 125 (context_->*bind_func_)(target, id); | |
| 150 } | 126 } |
| 151 | 127 |
| 152 virtual ~ScopedBinder() { | 128 virtual ~ScopedBinder() { |
| 153 if (id_ != 0) | 129 (context_->*bind_func_)(target, prev_id_); |
| 154 (context_->*bind_func_)(target, 0); | |
| 155 } | 130 } |
| 156 | 131 |
| 157 private: | 132 private: |
| 158 WebGraphicsContext3D* context_; | 133 WebGraphicsContext3D* context_; |
| 159 WebGLId id_; | 134 GLint prev_id_; |
| 160 BindFunc bind_func_; | 135 BindFunc bind_func_; |
| 161 | 136 |
| 162 DISALLOW_COPY_AND_ASSIGN(ScopedBinder); | 137 DISALLOW_COPY_AND_ASSIGN(ScopedBinder); |
| 163 }; | 138 }; |
| 164 | 139 |
| 165 template <WebKit::WGC3Denum target> | 140 template <WebKit::WGC3Denum target, |
| 166 class ScopedBufferBinder : ScopedBinder<target> { | 141 WebKit::WGC3Denum target_binding> |
| 142 class ScopedBufferBinder : ScopedBinder<target, target_binding> { | |
| 167 public: | 143 public: |
| 168 ScopedBufferBinder(WebGraphicsContext3D* context, | 144 ScopedBufferBinder(WebGraphicsContext3D* context, |
| 169 WebGLId id) | 145 WebGLId id) |
| 170 : ScopedBinder<target>( | 146 : ScopedBinder<target, target_binding>( |
| 171 context, | 147 context, |
| 172 id, | 148 id, |
| 173 &WebGraphicsContext3D::bindBuffer) {} | 149 &WebGraphicsContext3D::bindBuffer) {} |
| 174 }; | 150 }; |
| 175 | 151 |
| 176 template <WebKit::WGC3Denum target> | 152 template <WebKit::WGC3Denum target, |
| 177 class ScopedFramebufferBinder : ScopedBinder<target> { | 153 WebKit::WGC3Denum target_binding> |
| 154 class ScopedFramebufferBinder : ScopedBinder<target, target_binding> { | |
| 178 public: | 155 public: |
| 179 ScopedFramebufferBinder(WebGraphicsContext3D* context, | 156 ScopedFramebufferBinder(WebGraphicsContext3D* context, |
| 180 WebGLId id) | 157 WebGLId id) |
| 181 : ScopedBinder<target>( | 158 : ScopedBinder<target, target_binding>( |
| 182 context, | 159 context, |
| 183 id, | 160 id, |
| 184 &WebGraphicsContext3D::bindFramebuffer) {} | 161 &WebGraphicsContext3D::bindFramebuffer) {} |
| 185 }; | 162 }; |
| 186 | 163 |
| 187 template <WebKit::WGC3Denum target> | 164 template <WebKit::WGC3Denum target, |
| 188 class ScopedRenderbufferBinder : ScopedBinder<target> { | 165 WebKit::WGC3Denum target_binding> |
| 189 public: | 166 class ScopedTextureBinder : ScopedBinder<target, target_binding> { |
| 190 ScopedRenderbufferBinder(WebGraphicsContext3D* context, | |
| 191 WebGLId id) | |
| 192 : ScopedBinder<target>( | |
| 193 context, | |
| 194 id, | |
| 195 &WebGraphicsContext3D::bindRenderbuffer) {} | |
| 196 }; | |
| 197 | |
| 198 template <WebKit::WGC3Denum target> | |
| 199 class ScopedTextureBinder : ScopedBinder<target> { | |
| 200 public: | 167 public: |
| 201 ScopedTextureBinder(WebGraphicsContext3D* context, | 168 ScopedTextureBinder(WebGraphicsContext3D* context, |
| 202 WebGLId id) | 169 WebGLId id) |
| 203 : ScopedBinder<target>( | 170 : ScopedBinder<target, target_binding>( |
| 204 context, | 171 context, |
| 205 id, | 172 id, |
| 206 &WebGraphicsContext3D::bindTexture) {} | 173 &WebGraphicsContext3D::bindTexture) {} |
| 207 }; | 174 }; |
| 208 | 175 |
| 209 class ScopedFlush { | 176 class ScopedFlush { |
| 210 public: | 177 public: |
| 211 explicit ScopedFlush(WebGraphicsContext3D* context) | 178 explicit ScopedFlush(WebGraphicsContext3D* context) |
| 212 : context_(context) { | 179 : context_(context) { |
| 213 } | 180 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 229 void SignalWaitableEvent(base::WaitableEvent* event) { | 196 void SignalWaitableEvent(base::WaitableEvent* event) { |
| 230 event->Signal(); | 197 event->Signal(); |
| 231 } | 198 } |
| 232 | 199 |
| 233 } // namespace | 200 } // namespace |
| 234 | 201 |
| 235 namespace content { | 202 namespace content { |
| 236 | 203 |
| 237 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the | 204 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the |
| 238 // data needed for it. | 205 // data needed for it. |
| 239 class GLHelper::CopyTextureToImpl { | 206 class GLHelper::CopyTextureToImpl : |
| 207 public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> { | |
| 240 public: | 208 public: |
| 241 CopyTextureToImpl(WebGraphicsContext3D* context, | 209 CopyTextureToImpl(WebGraphicsContext3D* context, |
| 242 WebGraphicsContext3D* context_for_thread, | |
| 243 GLHelper* helper) | 210 GLHelper* helper) |
| 244 : context_(context), | 211 : context_(context), |
| 245 context_for_thread_(context_for_thread), | |
| 246 helper_(helper), | 212 helper_(helper), |
| 247 flush_(context), | 213 flush_(context), |
| 248 program_(context, context->createProgram()), | 214 program_(context, context->createProgram()), |
| 249 vertex_attributes_buffer_(context_, context_->createBuffer()), | 215 vertex_attributes_buffer_(context_, context_->createBuffer()), |
| 250 flipped_vertex_attributes_buffer_(context_, context_->createBuffer()) { | 216 flipped_vertex_attributes_buffer_(context_, context_->createBuffer()) { |
| 251 InitBuffer(); | 217 InitBuffer(); |
| 252 InitProgram(); | 218 InitProgram(); |
| 253 } | 219 } |
| 254 ~CopyTextureToImpl() { | 220 ~CopyTextureToImpl() { |
| 255 CancelRequests(); | 221 CancelRequests(); |
| 256 DeleteContextForThread(); | |
| 257 } | 222 } |
| 258 | 223 |
| 259 void InitBuffer(); | 224 void InitBuffer(); |
| 260 void InitProgram(); | 225 void InitProgram(); |
| 261 | 226 |
| 262 void CropScaleReadbackAndCleanTexture( | 227 void CropScaleReadbackAndCleanTexture( |
| 263 WebGLId src_texture, | 228 WebGLId src_texture, |
| 264 const gfx::Size& src_size, | 229 const gfx::Size& src_size, |
| 265 const gfx::Rect& src_subrect, | 230 const gfx::Rect& src_subrect, |
| 266 const gfx::Size& dst_size, | 231 const gfx::Size& dst_size, |
| 267 unsigned char* out, | 232 unsigned char* out, |
| 268 const base::Callback<void(bool)>& callback); | 233 const base::Callback<void(bool)>& callback); |
| 269 | 234 |
| 270 void ReadbackTextureSync(WebGLId texture, | 235 void ReadbackTextureSync(WebGLId texture, |
| 271 const gfx::Rect& src_rect, | 236 const gfx::Rect& src_rect, |
| 272 unsigned char* out); | 237 unsigned char* out); |
| 273 | 238 |
| 274 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture, | 239 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture, |
| 275 const gfx::Size& src_size, | 240 const gfx::Size& src_size, |
| 276 const gfx::Size& dst_size, | 241 const gfx::Size& dst_size, |
| 277 bool vertically_flip_texture); | 242 bool vertically_flip_texture); |
| 278 | 243 |
| 279 private: | 244 private: |
| 280 // A single request to CropScaleReadbackAndCleanTexture. | 245 // A single request to CropScaleReadbackAndCleanTexture. |
| 281 // Thread-safety notes: the main thread creates instances of this class. The | 246 // The main thread can cancel the request, before it's handled by the helper |
| 282 // main thread can cancel the request, before it's handled by the helper | |
| 283 // thread, by resetting the texture and pixels fields. Alternatively, the | 247 // thread, by resetting the texture and pixels fields. Alternatively, the |
| 284 // thread marks that it handles the request by resetting the pixels field | 248 // thread marks that it handles the request by resetting the pixels field |
| 285 // (meaning it guarantees that the callback with be called). | 249 // (meaning it guarantees that the callback with be called). |
| 286 // In either case, the callback must be called exactly once, and the texture | 250 // In either case, the callback must be called exactly once, and the texture |
| 287 // must be deleted by the main thread context. | 251 // must be deleted by the main thread context. |
| 288 struct Request : public base::RefCountedThreadSafe<Request> { | 252 struct Request { |
| 289 Request(CopyTextureToImpl* impl, | 253 Request(WebGLId texture_, |
| 290 WebGLId texture_, | |
| 291 const gfx::Size& size_, | 254 const gfx::Size& size_, |
| 292 unsigned char* pixels_, | 255 unsigned char* pixels_, |
| 293 const base::Callback<void(bool)>& callback_) | 256 const base::Callback<void(bool)>& callback_) |
| 294 : copy_texture_impl(impl), | 257 : size(size_), |
| 295 size(size_), | 258 callback(callback_), |
| 296 callback(callback_), | 259 texture(texture_), |
| 297 lock(), | 260 pixels(pixels_), |
| 298 texture(texture_), | 261 buffer(0), |
| 299 pixels(pixels_) { | 262 query(0) { |
| 300 } | 263 } |
| 301 | 264 |
| 302 // These members are only accessed on the main thread. | |
| 303 GLHelper::CopyTextureToImpl* copy_texture_impl; | |
| 304 gfx::Size size; | 265 gfx::Size size; |
| 305 base::Callback<void(bool)> callback; | 266 base::Callback<void(bool)> callback; |
| 306 | 267 |
| 307 // Locks access to below members, which can be accessed on any thread. | |
| 308 base::Lock lock; | |
| 309 WebGLId texture; | 268 WebGLId texture; |
| 310 unsigned char* pixels; | 269 unsigned char* pixels; |
| 311 | 270 GLuint buffer; |
| 312 private: | 271 GLuint query; |
| 313 friend class base::RefCountedThreadSafe<Request>; | |
| 314 ~Request() {} | |
| 315 }; | 272 }; |
| 316 | 273 |
| 317 // Copies the block of pixels specified with |src_subrect| from |src_texture|, | 274 // Copies the block of pixels specified with |src_subrect| from |src_texture|, |
| 318 // scales it to |dst_size|, writes it into a texture, and returns its ID. | 275 // scales it to |dst_size|, writes it into a texture, and returns its ID. |
| 319 // |src_size| is the size of |src_texture|. | 276 // |src_size| is the size of |src_texture|. |
| 320 WebGLId ScaleTexture(WebGLId src_texture, | 277 WebGLId ScaleTexture(WebGLId src_texture, |
| 321 const gfx::Size& src_size, | 278 const gfx::Size& src_size, |
| 322 const gfx::Rect& src_subrect, | 279 const gfx::Rect& src_subrect, |
| 323 const gfx::Size& dst_size, | 280 const gfx::Size& dst_size, |
| 324 bool vertically_flip_texture); | 281 bool vertically_flip_texture); |
| 325 | 282 |
| 326 // Deletes the context for GLHelperThread. | 283 void ScheduleCheckReadbackDone(); |
| 327 void DeleteContextForThread(); | 284 void CheckReadbackDone(); |
| 328 static void ReadBackFramebuffer(scoped_refptr<Request> request, | 285 void FinishRequest(Request* request, bool result); |
| 329 WebGraphicsContext3D* context, | |
| 330 scoped_refptr<base::TaskRunner> reply_loop); | |
| 331 static void ReadBackFramebufferComplete(scoped_refptr<Request> request, | |
| 332 bool result); | |
| 333 void FinishRequest(scoped_refptr<Request> request); | |
| 334 void CancelRequests(); | 286 void CancelRequests(); |
| 335 | 287 |
| 336 // Interleaved array of 2-dimentional vertex positions (x, y) and | 288 // Interleaved array of 2-dimentional vertex positions (x, y) and |
| 337 // 2-dimentional texture coordinates (s, t). | 289 // 2-dimentional texture coordinates (s, t). |
| 338 static const WebKit::WGC3Dfloat kVertexAttributes[]; | 290 static const WebKit::WGC3Dfloat kVertexAttributes[]; |
| 339 // Interleaved array of 2-dimensional vertex positions (x, y) and | 291 // Interleaved array of 2-dimensional vertex positions (x, y) and |
| 340 // 2 dimensional texture coordinates (s, t). | 292 // 2 dimensional texture coordinates (s, t). |
| 341 static const WebKit::WGC3Dfloat kFlippedVertexAttributes[]; | 293 static const WebKit::WGC3Dfloat kFlippedVertexAttributes[]; |
| 342 // Shader sources used for GLHelper::CropScaleReadbackAndCleanTexture and | 294 // Shader sources used for GLHelper::CropScaleReadbackAndCleanTexture and |
| 343 // GLHelper::ReadbackTextureSync | 295 // GLHelper::ReadbackTextureSync |
| 344 static const WebKit::WGC3Dchar kCopyVertexShader[]; | 296 static const WebKit::WGC3Dchar kCopyVertexShader[]; |
| 345 static const WebKit::WGC3Dchar kCopyFragmentShader[]; | 297 static const WebKit::WGC3Dchar kCopyFragmentShader[]; |
| 346 | 298 |
| 347 WebGraphicsContext3D* context_; | 299 WebGraphicsContext3D* context_; |
| 348 WebGraphicsContext3D* context_for_thread_; | |
| 349 GLHelper* helper_; | 300 GLHelper* helper_; |
| 350 | 301 |
| 351 // A scoped flush that will ensure all resource deletions are flushed when | 302 // A scoped flush that will ensure all resource deletions are flushed when |
| 352 // this object is destroyed. Must be declared before other Scoped* fields. | 303 // this object is destroyed. Must be declared before other Scoped* fields. |
| 353 ScopedFlush flush_; | 304 ScopedFlush flush_; |
| 354 // A program for copying a source texture into a destination texture. | 305 // A program for copying a source texture into a destination texture. |
| 355 ScopedProgram program_; | 306 ScopedProgram program_; |
| 356 // The buffer that holds the vertices and the texture coordinates data for | 307 // The buffer that holds the vertices and the texture coordinates data for |
| 357 // drawing a quad. | 308 // drawing a quad. |
| 358 ScopedBuffer vertex_attributes_buffer_; | 309 ScopedBuffer vertex_attributes_buffer_; |
| 359 ScopedBuffer flipped_vertex_attributes_buffer_; | 310 ScopedBuffer flipped_vertex_attributes_buffer_; |
| 360 | 311 |
| 361 // The location of the position in the program. | 312 // The location of the position in the program. |
| 362 WebKit::WGC3Dint position_location_; | 313 WebKit::WGC3Dint position_location_; |
| 363 // The location of the texture coordinate in the program. | 314 // The location of the texture coordinate in the program. |
| 364 WebKit::WGC3Dint texcoord_location_; | 315 WebKit::WGC3Dint texcoord_location_; |
| 365 // The location of the source texture in the program. | 316 // The location of the source texture in the program. |
| 366 WebKit::WGC3Dint texture_location_; | 317 WebKit::WGC3Dint texture_location_; |
| 367 // The location of the texture coordinate of the sub-rectangle in the program. | 318 // The location of the texture coordinate of the sub-rectangle in the program. |
| 368 WebKit::WGC3Dint src_subrect_location_; | 319 WebKit::WGC3Dint src_subrect_location_; |
| 369 std::queue<scoped_refptr<Request> > request_queue_; | 320 std::queue<Request*> request_queue_; |
| 370 }; | 321 }; |
| 371 | 322 |
| 372 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = { | 323 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = { |
| 373 -1.0f, -1.0f, 0.0f, 0.0f, | 324 -1.0f, -1.0f, 0.0f, 0.0f, |
| 374 1.0f, -1.0f, 1.0f, 0.0f, | 325 1.0f, -1.0f, 1.0f, 0.0f, |
| 375 -1.0f, 1.0f, 0.0f, 1.0f, | 326 -1.0f, 1.0f, 0.0f, 1.0f, |
| 376 1.0f, 1.0f, 1.0f, 1.0f, | 327 1.0f, 1.0f, 1.0f, 1.0f, |
| 377 }; | 328 }; |
| 378 | 329 |
| 379 const WebKit::WGC3Dfloat | 330 const WebKit::WGC3Dfloat |
| 380 GLHelper::CopyTextureToImpl::kFlippedVertexAttributes[] = { | 331 GLHelper::CopyTextureToImpl::kFlippedVertexAttributes[] = { |
| 381 -1.0f, -1.0f, 0.0f, 1.0f, | 332 -1.0f, -1.0f, 0.0f, 1.0f, |
| 382 1.0f, -1.0f, 1.0f, 1.0f, | 333 1.0f, -1.0f, 1.0f, 1.0f, |
| 383 -1.0f, 1.0f, 0.0f, 0.0f, | 334 -1.0f, 1.0f, 0.0f, 0.0f, |
| 384 1.0f, 1.0f, 1.0f, 0.0f, | 335 1.0f, 1.0f, 1.0f, 0.0f, |
| 385 }; | 336 }; |
| 386 | 337 |
| 387 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] = | 338 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] = |
| 388 "attribute vec2 a_position;" | 339 "attribute vec2 a_position;" |
| 389 "attribute vec2 a_texcoord;" | 340 "attribute vec2 a_texcoord;" |
| 390 "varying vec2 v_texcoord;" | 341 "varying vec2 v_texcoord;" |
| 391 "uniform vec4 src_subrect;" | 342 "uniform vec4 src_subrect;" |
| 392 "void main() {" | 343 "void main() {" |
| 393 " gl_Position = vec4(a_position, 0.0, 1.0);" | 344 " gl_Position = vec4(a_position, 0.0, 1.0);" |
| 394 " v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;" | 345 " v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;" |
| 395 "}"; | 346 "}"; |
| 396 | 347 |
| 348 | |
| 349 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | |
| 397 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = | 350 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = |
| 398 "precision mediump float;" | 351 "precision mediump float;" |
| 399 "varying vec2 v_texcoord;" | 352 "varying vec2 v_texcoord;" |
| 353 "uniform sampler2D s_texture;" | |
| 354 "void main() {" | |
| 355 " gl_FragColor = texture2D(s_texture, v_texcoord).bgra;" | |
| 356 "}"; | |
| 357 #else | |
| 358 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = | |
| 359 "precision mediump float;" | |
| 360 "varying vec2 v_texcoord;" | |
| 400 "uniform sampler2D s_texture;" | 361 "uniform sampler2D s_texture;" |
| 401 "void main() {" | 362 "void main() {" |
| 402 " gl_FragColor = texture2D(s_texture, v_texcoord);" | 363 " gl_FragColor = texture2D(s_texture, v_texcoord);" |
| 403 "}"; | 364 "}"; |
| 365 #endif | |
| 366 | |
| 404 | 367 |
| 405 void GLHelper::CopyTextureToImpl::InitBuffer() { | 368 void GLHelper::CopyTextureToImpl::InitBuffer() { |
| 406 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( | 369 ScopedBufferBinder<GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING> buffer_binder( |
| 407 context_, vertex_attributes_buffer_); | 370 context_, vertex_attributes_buffer_); |
| 408 context_->bufferData(GL_ARRAY_BUFFER, | 371 context_->bufferData(GL_ARRAY_BUFFER, |
| 409 sizeof(kVertexAttributes), | 372 sizeof(kVertexAttributes), |
| 410 kVertexAttributes, | 373 kVertexAttributes, |
| 411 GL_STATIC_DRAW); | 374 GL_STATIC_DRAW); |
| 412 ScopedBufferBinder<GL_ARRAY_BUFFER> flipped_buffer_binder( | 375 ScopedBufferBinder<GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING> |
| 413 context_, flipped_vertex_attributes_buffer_); | 376 flipped_buffer_binder( context_, flipped_vertex_attributes_buffer_); |
| 414 context_->bufferData(GL_ARRAY_BUFFER, | 377 context_->bufferData(GL_ARRAY_BUFFER, |
| 415 sizeof(kFlippedVertexAttributes), | 378 sizeof(kFlippedVertexAttributes), |
| 416 kFlippedVertexAttributes, | 379 kFlippedVertexAttributes, |
| 417 GL_STATIC_DRAW); | 380 GL_STATIC_DRAW); |
| 418 } | 381 } |
| 419 | 382 |
| 420 void GLHelper::CopyTextureToImpl::InitProgram() { | 383 void GLHelper::CopyTextureToImpl::InitProgram() { |
| 421 // Shaders to map the source texture to |dst_texture_|. | 384 // Shaders to map the source texture to |dst_texture_|. |
| 422 ScopedShader vertex_shader(context_, helper_->CompileShaderFromSource( | 385 ScopedShader vertex_shader(context_, helper_->CompileShaderFromSource( |
| 423 kCopyVertexShader, GL_VERTEX_SHADER)); | 386 kCopyVertexShader, GL_VERTEX_SHADER)); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 444 | 407 |
| 445 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( | 408 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( |
| 446 WebGLId src_texture, | 409 WebGLId src_texture, |
| 447 const gfx::Size& src_size, | 410 const gfx::Size& src_size, |
| 448 const gfx::Rect& src_subrect, | 411 const gfx::Rect& src_subrect, |
| 449 const gfx::Size& dst_size, | 412 const gfx::Size& dst_size, |
| 450 bool vertically_flip_texture) { | 413 bool vertically_flip_texture) { |
| 451 WebGLId dst_texture = context_->createTexture(); | 414 WebGLId dst_texture = context_->createTexture(); |
| 452 { | 415 { |
| 453 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 416 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
| 454 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 417 ScopedFramebufferBinder<GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING> |
| 455 context_, dst_framebuffer); | 418 framebuffer_binder(context_, dst_framebuffer); |
| 456 { | 419 { |
| 457 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( | 420 ScopedTextureBinder<GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D> texture_binder( |
| 458 context_, dst_texture); | 421 context_, dst_texture); |
| 459 context_->texImage2D(GL_TEXTURE_2D, | 422 context_->texImage2D(GL_TEXTURE_2D, |
| 460 0, | 423 0, |
| 461 GL_RGBA, | 424 GL_RGBA, |
| 462 dst_size.width(), | 425 dst_size.width(), |
| 463 dst_size.height(), | 426 dst_size.height(), |
| 464 0, | 427 0, |
| 465 GL_RGBA, | 428 GL_RGBA, |
| 466 GL_UNSIGNED_BYTE, | 429 GL_UNSIGNED_BYTE, |
| 467 NULL); | 430 NULL); |
| 468 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 431 context_->framebufferTexture2D(GL_FRAMEBUFFER, |
| 469 GL_COLOR_ATTACHMENT0, | 432 GL_COLOR_ATTACHMENT0, |
| 470 GL_TEXTURE_2D, | 433 GL_TEXTURE_2D, |
| 471 dst_texture, | 434 dst_texture, |
| 472 0); | 435 0); |
| 473 } | 436 } |
| 474 | 437 |
| 475 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, src_texture); | 438 ScopedTextureBinder<GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D> texture_binder( |
| 439 context_, src_texture); | |
| 476 WebKit::WebGLId vertex_attributes_buffer = vertically_flip_texture ? | 440 WebKit::WebGLId vertex_attributes_buffer = vertically_flip_texture ? |
| 477 flipped_vertex_attributes_buffer_ : vertex_attributes_buffer_; | 441 flipped_vertex_attributes_buffer_ : vertex_attributes_buffer_; |
| 478 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( | 442 ScopedBufferBinder<GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING> buffer_binder( |
| 479 context_, vertex_attributes_buffer); | 443 context_, vertex_attributes_buffer); |
| 480 | 444 |
| 481 context_->viewport(0, 0, dst_size.width(), dst_size.height()); | 445 context_->viewport(0, 0, dst_size.width(), dst_size.height()); |
| 482 context_->useProgram(program_); | 446 context_->useProgram(program_); |
| 483 | 447 |
| 484 WebKit::WGC3Dintptr offset = 0; | 448 WebKit::WGC3Dintptr offset = 0; |
| 485 context_->vertexAttribPointer(position_location_, | 449 context_->vertexAttribPointer(position_location_, |
| 486 2, | 450 2, |
| 487 GL_FLOAT, | 451 GL_FLOAT, |
| 488 GL_FALSE, | 452 GL_FALSE, |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 510 }; | 474 }; |
| 511 | 475 |
| 512 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord); | 476 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord); |
| 513 | 477 |
| 514 // Conduct texture mapping by drawing a quad composed of two triangles. | 478 // Conduct texture mapping by drawing a quad composed of two triangles. |
| 515 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); | 479 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 516 } | 480 } |
| 517 return dst_texture; | 481 return dst_texture; |
| 518 } | 482 } |
| 519 | 483 |
| 520 void GLHelper::CopyTextureToImpl::DeleteContextForThread() { | |
| 521 if (!context_for_thread_) | |
| 522 return; | |
| 523 | |
| 524 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask( | |
| 525 FROM_HERE, | |
| 526 base::Bind(&DeleteContext, | |
| 527 context_for_thread_)); | |
| 528 context_for_thread_ = NULL; | |
| 529 } | |
| 530 | |
| 531 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 484 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| 532 WebGLId src_texture, | 485 WebGLId src_texture, |
| 533 const gfx::Size& src_size, | 486 const gfx::Size& src_size, |
| 534 const gfx::Rect& src_subrect, | 487 const gfx::Rect& src_subrect, |
| 535 const gfx::Size& dst_size, | 488 const gfx::Size& dst_size, |
| 536 unsigned char* out, | 489 unsigned char* out, |
| 537 const base::Callback<void(bool)>& callback) { | 490 const base::Callback<void(bool)>& callback) { |
| 538 if (!context_for_thread_) { | |
| 539 callback.Run(false); | |
| 540 return; | |
| 541 } | |
| 542 | |
| 543 WebGLId texture = ScaleTexture(src_texture, | 491 WebGLId texture = ScaleTexture(src_texture, |
| 544 src_size, | 492 src_size, |
| 545 src_subrect, | 493 src_subrect, |
| 546 dst_size, | 494 dst_size, |
| 547 false); | 495 #ifdef USE_SKIA |
| 496 true | |
| 497 #else | |
| 498 false | |
| 499 #endif | |
| 500 ); | |
| 548 context_->flush(); | 501 context_->flush(); |
| 549 scoped_refptr<Request> request = | 502 Request *request = new Request(texture, dst_size, out, callback); |
| 550 new Request(this, texture, dst_size, out, callback); | |
| 551 request_queue_.push(request); | 503 request_queue_.push(request); |
| 504 if (request_queue_.size() == 1) { | |
| 505 ScheduleCheckReadbackDone(); | |
| 506 } | |
| 552 | 507 |
| 553 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, | 508 ScopedFlush flush(context_); |
| 554 base::Bind(&ReadBackFramebuffer, | 509 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
| 555 request, | 510 gfx::Size size; |
| 556 context_for_thread_, | 511 size = request->size; |
| 557 base::MessageLoopProxy::current())); | 512 |
| 513 ScopedFramebufferBinder<GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING> | |
| 514 framebuffer_binder(context_, dst_framebuffer); | |
| 515 ScopedTextureBinder<GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D> texture_binder( | |
| 516 context_, request->texture); | |
| 517 context_->framebufferTexture2D(GL_FRAMEBUFFER, | |
| 518 GL_COLOR_ATTACHMENT0, | |
| 519 GL_TEXTURE_2D, | |
| 520 request->texture, | |
| 521 0); | |
| 522 request->buffer = context_->createBuffer(); | |
| 523 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 524 request->buffer); | |
| 525 context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 526 4 * size.GetArea(), | |
| 527 NULL, | |
| 528 GL_STREAM_READ); | |
| 529 | |
| 530 request->query = context_->createQueryEXT(); | |
| 531 context_->beginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, request->query); | |
| 532 context_->readPixels(0, 0, size.width(), size.height(), | |
| 533 GL_RGBA, GL_UNSIGNED_BYTE, 0); | |
| 534 context_->endQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM); | |
| 535 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 536 | |
| 558 } | 537 } |
| 559 | 538 |
| 560 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture, | 539 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture, |
| 561 const gfx::Rect& src_rect, | 540 const gfx::Rect& src_rect, |
| 562 unsigned char* out) { | 541 unsigned char* out) { |
| 563 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 542 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
| 564 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 543 ScopedFramebufferBinder<GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING> |
| 565 context_, dst_framebuffer); | 544 framebuffer_binder(context_, dst_framebuffer); |
| 566 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 545 ScopedTextureBinder<GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D> texture_binder( |
| 546 context_, texture); | |
| 567 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 547 context_->framebufferTexture2D(GL_FRAMEBUFFER, |
| 568 GL_COLOR_ATTACHMENT0, | 548 GL_COLOR_ATTACHMENT0, |
| 569 GL_TEXTURE_2D, | 549 GL_TEXTURE_2D, |
| 570 texture, | 550 texture, |
| 571 0); | 551 0); |
| 572 context_->readPixels(src_rect.x(), | 552 context_->readPixels(src_rect.x(), |
| 573 src_rect.y(), | 553 src_rect.y(), |
| 574 src_rect.width(), | 554 src_rect.width(), |
| 575 src_rect.height(), | 555 src_rect.height(), |
| 576 GL_RGBA, | 556 GL_RGBA, |
| 577 GL_UNSIGNED_BYTE, | 557 GL_UNSIGNED_BYTE, |
| 578 out); | 558 out); |
| 579 } | 559 } |
| 580 | 560 |
| 581 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 561 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
| 582 WebGLId src_texture, | 562 WebGLId src_texture, |
| 583 const gfx::Size& src_size, | 563 const gfx::Size& src_size, |
| 584 const gfx::Size& dst_size, | 564 const gfx::Size& dst_size, |
| 585 bool vertically_flip_texture) { | 565 bool vertically_flip_texture) { |
| 586 return ScaleTexture(src_texture, | 566 return ScaleTexture(src_texture, |
| 587 src_size, | 567 src_size, |
| 588 gfx::Rect(src_size), | 568 gfx::Rect(src_size), |
| 589 dst_size, | 569 dst_size, |
| 590 vertically_flip_texture); | 570 vertically_flip_texture); |
| 591 } | 571 } |
| 592 | 572 |
| 593 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer( | 573 |
| 594 scoped_refptr<Request> request, | 574 void GLHelper::CopyTextureToImpl::ScheduleCheckReadbackDone() { |
| 595 WebGraphicsContext3D* context, | 575 DCHECK(!request_queue_.empty()); |
| 596 scoped_refptr<base::TaskRunner> reply_loop) { | 576 base::MessageLoopProxy::current()->PostDelayedTask( |
| 597 DCHECK(context); | 577 FROM_HERE, |
| 598 if (!context->makeContextCurrent() || context->isContextLost()) { | 578 base::Bind(&CopyTextureToImpl::CheckReadbackDone, AsWeakPtr()), |
| 599 base::AutoLock auto_lock(request->lock); | 579 base::TimeDelta::FromMilliseconds(2)); |
| 600 if (request->pixels) { | |
| 601 // Only report failure if the request wasn't canceled (otherwise the | |
| 602 // failure has already been reported). | |
| 603 request->pixels = NULL; | |
| 604 reply_loop->PostTask( | |
| 605 FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, false)); | |
| 606 } | |
| 607 return; | |
| 608 } | |
| 609 ScopedFlush flush(context); | |
| 610 ScopedFramebuffer dst_framebuffer(context, context->createFramebuffer()); | |
| 611 unsigned char* pixels = NULL; | |
| 612 gfx::Size size; | |
| 613 { | |
| 614 // Note: We don't want to keep the lock while doing the readBack (since we | |
| 615 // don't want to block the UI thread). We rely on the fact that once the | |
| 616 // texture is bound to a FBO (that isn't current), deleting the texture is | |
| 617 // delayed until the FBO is deleted. We ensure ordering by flushing while | |
| 618 // the lock is held. Either the main thread cancelled before we get the | |
| 619 // lock, and we'll exit early, or we ensure that the texture is bound to the | |
| 620 // framebuffer before the main thread has a chance to delete it. | |
| 621 base::AutoLock auto_lock(request->lock); | |
| 622 if (!request->texture || !request->pixels) | |
| 623 return; | |
| 624 pixels = request->pixels; | |
| 625 request->pixels = NULL; | |
| 626 size = request->size; | |
| 627 { | |
| 628 ScopedFlush flush(context); | |
| 629 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | |
| 630 context, dst_framebuffer); | |
| 631 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( | |
| 632 context, request->texture); | |
| 633 context->framebufferTexture2D(GL_FRAMEBUFFER, | |
| 634 GL_COLOR_ATTACHMENT0, | |
| 635 GL_TEXTURE_2D, | |
| 636 request->texture, | |
| 637 0); | |
| 638 } | |
| 639 } | |
| 640 bool result = context->readBackFramebuffer( | |
| 641 pixels, | |
| 642 4 * size.GetArea(), | |
| 643 dst_framebuffer.id(), | |
| 644 size.width(), | |
| 645 size.height()); | |
| 646 reply_loop->PostTask( | |
| 647 FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, result)); | |
| 648 } | 580 } |
| 649 | 581 |
| 650 void GLHelper::CopyTextureToImpl::ReadBackFramebufferComplete( | 582 void GLHelper::CopyTextureToImpl::CheckReadbackDone() { |
| 651 scoped_refptr<Request> request, | 583 TRACE_EVENT0("mirror", |
| 652 bool result) { | 584 "GLHelper::CopyTextureToImpl::CheckReadBackFramebufferComplete"); |
| 653 request->callback.Run(result); | 585 while (!request_queue_.empty()) { |
| 654 if (request->copy_texture_impl) | 586 Request* request = request_queue_.front(); |
| 655 request->copy_texture_impl->FinishRequest(request); | 587 |
| 588 bool result = false; | |
| 589 if (request->buffer != 0) { | |
| 590 unsigned int done = 1; | |
| 591 context_->getQueryObjectuivEXT(request->query, | |
| 592 GL_QUERY_RESULT_AVAILABLE_EXT, &done); | |
| 593 if (!done) { | |
| 594 ScheduleCheckReadbackDone(); | |
| 595 return; | |
| 596 } | |
| 597 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | |
| 598 request->buffer); | |
| 599 void* data = context_->mapBufferCHROMIUM( | |
| 600 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY); | |
| 601 | |
| 602 if (data) { | |
| 603 result = true; | |
| 604 memcpy(request->pixels, data, request->size.GetArea() * 4); | |
| 605 context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); | |
| 606 } | |
| 607 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 608 } | |
| 609 | |
| 610 FinishRequest(request, result); | |
| 611 } | |
| 656 } | 612 } |
| 657 | 613 |
| 658 void GLHelper::CopyTextureToImpl::FinishRequest( | 614 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) { |
| 659 scoped_refptr<Request> request) { | 615 DCHECK(request_queue_.front() == request); |
| 660 CHECK(request_queue_.front() == request); | |
| 661 request_queue_.pop(); | 616 request_queue_.pop(); |
| 662 base::AutoLock auto_lock(request->lock); | 617 request->callback.Run(result); |
| 663 if (request->texture != 0) { | 618 if (request->texture != 0) { |
| 664 context_->deleteTexture(request->texture); | 619 context_->deleteTexture(request->texture); |
| 665 request->texture = 0; | 620 request->texture = 0; |
| 666 context_->flush(); | 621 context_->flush(); |
| 667 } | 622 } |
| 623 if (request->buffer != 0) { | |
| 624 context_->deleteBuffer(request->buffer); | |
| 625 request->buffer = 0; | |
| 626 context_->flush(); | |
| 627 } | |
| 628 if (request->query != 0) { | |
| 629 context_->deleteQueryEXT(request->query); | |
| 630 request->query = 0; | |
| 631 context_->flush(); | |
| 632 } | |
| 633 delete request; | |
| 668 } | 634 } |
| 669 | 635 |
| 670 void GLHelper::CopyTextureToImpl::CancelRequests() { | 636 void GLHelper::CopyTextureToImpl::CancelRequests() { |
| 671 while (!request_queue_.empty()) { | 637 while (!request_queue_.empty()) { |
| 672 scoped_refptr<Request> request = request_queue_.front(); | 638 Request* request = request_queue_.front(); |
| 673 request_queue_.pop(); | 639 FinishRequest(request, false); |
| 674 request->copy_texture_impl = NULL; | |
| 675 bool cancelled = false; | |
| 676 { | |
| 677 base::AutoLock auto_lock(request->lock); | |
| 678 if (request->texture != 0) { | |
| 679 context_->deleteTexture(request->texture); | |
| 680 request->texture = 0; | |
| 681 } | |
| 682 if (request->pixels != NULL) { | |
| 683 request->pixels = NULL; | |
| 684 cancelled = true; | |
| 685 } | |
| 686 } | |
| 687 if (cancelled) | |
| 688 request->callback.Run(false); | |
| 689 } | 640 } |
| 690 } | 641 } |
| 691 | 642 |
| 692 base::subtle::Atomic32 GLHelper::count_ = 0; | 643 GLHelper::GLHelper(WebGraphicsContext3D* context) |
| 693 | 644 : context_(context) { |
| 694 GLHelper::GLHelper(WebGraphicsContext3D* context, | |
| 695 WebGraphicsContext3D* context_for_thread) | |
| 696 : context_(context), | |
| 697 context_for_thread_(context_for_thread) { | |
| 698 base::subtle::NoBarrier_AtomicIncrement(&count_, 1); | |
| 699 } | 645 } |
| 700 | 646 |
| 701 GLHelper::~GLHelper() { | 647 GLHelper::~GLHelper() { |
| 702 DCHECK_NE(MessageLoop::current(), | |
| 703 g_gl_helper_thread.Pointer()->message_loop()); | |
| 704 base::subtle::Atomic32 decremented_count = | |
| 705 base::subtle::NoBarrier_AtomicIncrement(&count_, -1); | |
| 706 if (decremented_count == 0) { | |
| 707 // When this is the last instance, we synchronize with the pending | |
| 708 // operations on GLHelperThread. Otherwise on shutdown we may kill the GPU | |
| 709 // process infrastructure (BrowserGpuChannelHostFactory) before they have | |
| 710 // a chance to complete, likely leading to a crash. | |
| 711 base::WaitableEvent event(false, false); | |
| 712 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask( | |
| 713 FROM_HERE, | |
| 714 base::Bind(&SignalWaitableEvent, | |
| 715 &event)); | |
| 716 // http://crbug.com/125415 | |
| 717 base::ThreadRestrictions::ScopedAllowWait allow_wait; | |
| 718 event.Wait(); | |
| 719 } | |
| 720 } | 648 } |
| 721 | 649 |
| 722 WebGraphicsContext3D* GLHelper::context() const { | 650 WebGraphicsContext3D* GLHelper::context() const { |
| 723 return context_; | 651 return context_; |
| 724 } | 652 } |
| 725 | 653 |
| 726 void GLHelper::CropScaleReadbackAndCleanTexture( | 654 void GLHelper::CropScaleReadbackAndCleanTexture( |
| 727 WebGLId src_texture, | 655 WebGLId src_texture, |
| 728 const gfx::Size& src_size, | 656 const gfx::Size& src_size, |
| 729 const gfx::Rect& src_subrect, | 657 const gfx::Rect& src_subrect, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 779 if (!compile_status) { | 707 if (!compile_status) { |
| 780 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); | 708 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); |
| 781 return 0; | 709 return 0; |
| 782 } | 710 } |
| 783 return shader.Detach(); | 711 return shader.Detach(); |
| 784 } | 712 } |
| 785 | 713 |
| 786 void GLHelper::InitCopyTextToImpl() { | 714 void GLHelper::InitCopyTextToImpl() { |
| 787 // Lazily initialize |copy_texture_to_impl_| | 715 // Lazily initialize |copy_texture_to_impl_| |
| 788 if (!copy_texture_to_impl_.get()) | 716 if (!copy_texture_to_impl_.get()) |
| 789 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, | 717 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, this)); |
| 790 context_for_thread_, | |
| 791 this)); | |
| 792 } | 718 } |
| 793 | 719 |
| 794 void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture, | 720 void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture, |
| 795 WebKit::WebGLId previous_texture, | 721 WebKit::WebGLId previous_texture, |
| 796 const SkRegion& new_damage, | 722 const SkRegion& new_damage, |
| 797 const SkRegion& old_damage) { | 723 const SkRegion& old_damage) { |
| 798 SkRegion region(old_damage); | 724 SkRegion region(old_damage); |
| 799 if (region.op(new_damage, SkRegion::kDifference_Op)) { | 725 if (region.op(new_damage, SkRegion::kDifference_Op)) { |
| 800 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 726 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
| 801 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 727 ScopedFramebufferBinder<GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING> |
| 802 context_, dst_framebuffer); | 728 framebuffer_binder(context_, dst_framebuffer); |
| 803 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 729 ScopedTextureBinder<GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D> texture_binder( |
| 730 context_, texture); | |
| 804 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 731 context_->framebufferTexture2D(GL_FRAMEBUFFER, |
| 805 GL_COLOR_ATTACHMENT0, | 732 GL_COLOR_ATTACHMENT0, |
| 806 GL_TEXTURE_2D, | 733 GL_TEXTURE_2D, |
| 807 previous_texture, | 734 previous_texture, |
| 808 0); | 735 0); |
| 809 for (SkRegion::Iterator it(region); !it.done(); it.next()) { | 736 for (SkRegion::Iterator it(region); !it.done(); it.next()) { |
| 810 const SkIRect& rect = it.rect(); | 737 const SkIRect& rect = it.rect(); |
| 811 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0, | 738 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0, |
| 812 rect.x(), rect.y(), | 739 rect.x(), rect.y(), |
| 813 rect.x(), rect.y(), | 740 rect.x(), rect.y(), |
| 814 rect.width(), rect.height()); | 741 rect.width(), rect.height()); |
| 815 } | 742 } |
| 816 context_->flush(); | 743 context_->flush(); |
| 817 } | 744 } |
| 818 } | 745 } |
| 819 | 746 |
| 820 } // namespace content | 747 } // namespace content |
| OLD | NEW |