| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2010, Google Inc. All rights reserved. | 2 * Copyright (c) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 #include "wtf/typed_arrays/ArrayBufferContents.h" | 52 #include "wtf/typed_arrays/ArrayBufferContents.h" |
| 53 #include <algorithm> | 53 #include <algorithm> |
| 54 #include <memory> | 54 #include <memory> |
| 55 | 55 |
| 56 namespace blink { | 56 namespace blink { |
| 57 | 57 |
| 58 namespace { | 58 namespace { |
| 59 | 59 |
| 60 const float s_resourceAdjustedRatio = 0.5; | 60 const float s_resourceAdjustedRatio = 0.5; |
| 61 | 61 |
| 62 class ScopedTextureUnit0BindingRestorer { | |
| 63 STACK_ALLOCATED(); | |
| 64 WTF_MAKE_NONCOPYABLE(ScopedTextureUnit0BindingRestorer); | |
| 65 | |
| 66 public: | |
| 67 ScopedTextureUnit0BindingRestorer(gpu::gles2::GLES2Interface* gl, | |
| 68 GLenum activeTextureUnit, | |
| 69 GLuint textureUnitZeroId) | |
| 70 : m_gl(gl), | |
| 71 m_oldActiveTextureUnit(activeTextureUnit), | |
| 72 m_oldTextureUnitZeroId(textureUnitZeroId) { | |
| 73 m_gl->ActiveTexture(GL_TEXTURE0); | |
| 74 } | |
| 75 ~ScopedTextureUnit0BindingRestorer() { | |
| 76 m_gl->BindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); | |
| 77 m_gl->ActiveTexture(m_oldActiveTextureUnit); | |
| 78 } | |
| 79 | |
| 80 private: | |
| 81 gpu::gles2::GLES2Interface* m_gl; | |
| 82 GLenum m_oldActiveTextureUnit; | |
| 83 GLuint m_oldTextureUnitZeroId; | |
| 84 }; | |
| 85 | |
| 86 static bool shouldFailDrawingBufferCreationForTesting = false; | 62 static bool shouldFailDrawingBufferCreationForTesting = false; |
| 87 | 63 |
| 88 } // namespace | 64 } // namespace |
| 89 | 65 |
| 90 PassRefPtr<DrawingBuffer> DrawingBuffer::create( | 66 PassRefPtr<DrawingBuffer> DrawingBuffer::create( |
| 91 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 67 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, |
| 68 Client* client, |
| 92 const IntSize& size, | 69 const IntSize& size, |
| 93 bool premultipliedAlpha, | 70 bool premultipliedAlpha, |
| 94 bool wantAlphaChannel, | 71 bool wantAlphaChannel, |
| 95 bool wantDepthBuffer, | 72 bool wantDepthBuffer, |
| 96 bool wantStencilBuffer, | 73 bool wantStencilBuffer, |
| 97 bool wantAntialiasing, | 74 bool wantAntialiasing, |
| 98 PreserveDrawingBuffer preserve, | 75 PreserveDrawingBuffer preserve, |
| 99 WebGLVersion webGLVersion, | 76 WebGLVersion webGLVersion, |
| 100 ChromiumImageUsage chromiumImageUsage) { | 77 ChromiumImageUsage chromiumImageUsage) { |
| 101 ASSERT(contextProvider); | 78 ASSERT(contextProvider); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 128 else | 105 else |
| 129 extensionsUtil->ensureExtensionEnabled( | 106 extensionsUtil->ensureExtensionEnabled( |
| 130 "GL_EXT_multisampled_render_to_texture"); | 107 "GL_EXT_multisampled_render_to_texture"); |
| 131 } | 108 } |
| 132 bool discardFramebufferSupported = | 109 bool discardFramebufferSupported = |
| 133 extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); | 110 extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); |
| 134 if (discardFramebufferSupported) | 111 if (discardFramebufferSupported) |
| 135 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 112 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); |
| 136 | 113 |
| 137 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( | 114 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( |
| 138 std::move(contextProvider), std::move(extensionsUtil), | 115 std::move(contextProvider), std::move(extensionsUtil), client, |
| 139 discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, | 116 discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, |
| 140 preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, | 117 preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, |
| 141 chromiumImageUsage)); | 118 chromiumImageUsage)); |
| 142 if (!drawingBuffer->initialize(size, multisampleSupported)) { | 119 if (!drawingBuffer->initialize(size, multisampleSupported)) { |
| 143 drawingBuffer->beginDestruction(); | 120 drawingBuffer->beginDestruction(); |
| 144 return PassRefPtr<DrawingBuffer>(); | 121 return PassRefPtr<DrawingBuffer>(); |
| 145 } | 122 } |
| 146 return drawingBuffer.release(); | 123 return drawingBuffer.release(); |
| 147 } | 124 } |
| 148 | 125 |
| 149 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { | 126 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { |
| 150 shouldFailDrawingBufferCreationForTesting = true; | 127 shouldFailDrawingBufferCreationForTesting = true; |
| 151 } | 128 } |
| 152 | 129 |
| 153 DrawingBuffer::DrawingBuffer( | 130 DrawingBuffer::DrawingBuffer( |
| 154 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 131 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, |
| 155 std::unique_ptr<Extensions3DUtil> extensionsUtil, | 132 std::unique_ptr<Extensions3DUtil> extensionsUtil, |
| 133 Client* client, |
| 156 bool discardFramebufferSupported, | 134 bool discardFramebufferSupported, |
| 157 bool wantAlphaChannel, | 135 bool wantAlphaChannel, |
| 158 bool premultipliedAlpha, | 136 bool premultipliedAlpha, |
| 159 PreserveDrawingBuffer preserve, | 137 PreserveDrawingBuffer preserve, |
| 160 WebGLVersion webGLVersion, | 138 WebGLVersion webGLVersion, |
| 161 bool wantDepth, | 139 bool wantDepth, |
| 162 bool wantStencil, | 140 bool wantStencil, |
| 163 ChromiumImageUsage chromiumImageUsage) | 141 ChromiumImageUsage chromiumImageUsage) |
| 164 : m_preserveDrawingBuffer(preserve), | 142 : m_client(client), |
| 143 m_preserveDrawingBuffer(preserve), |
| 165 m_webGLVersion(webGLVersion), | 144 m_webGLVersion(webGLVersion), |
| 166 m_contextProvider(std::move(contextProvider)), | 145 m_contextProvider(std::move(contextProvider)), |
| 167 m_gl(m_contextProvider->contextGL()), | 146 m_gl(m_contextProvider->contextGL()), |
| 168 m_extensionsUtil(std::move(extensionsUtil)), | 147 m_extensionsUtil(std::move(extensionsUtil)), |
| 169 m_discardFramebufferSupported(discardFramebufferSupported), | 148 m_discardFramebufferSupported(discardFramebufferSupported), |
| 170 m_wantAlphaChannel(wantAlphaChannel), | 149 m_wantAlphaChannel(wantAlphaChannel), |
| 171 m_premultipliedAlpha(premultipliedAlpha), | 150 m_premultipliedAlpha(premultipliedAlpha), |
| 172 m_softwareRendering(m_contextProvider->isSoftwareRendering()), | 151 m_softwareRendering(m_contextProvider->isSoftwareRendering()), |
| 173 m_wantDepth(wantDepth), | 152 m_wantDepth(wantDepth), |
| 174 m_wantStencil(wantStencil), | 153 m_wantStencil(wantStencil), |
| 175 m_chromiumImageUsage(chromiumImageUsage) { | 154 m_chromiumImageUsage(chromiumImageUsage) { |
| 176 memset(m_colorMask, 0, 4 * sizeof(GLboolean)); | |
| 177 memset(m_clearColor, 0, 4 * sizeof(GLfloat)); | |
| 178 // Used by browser tests to detect the use of a DrawingBuffer. | 155 // Used by browser tests to detect the use of a DrawingBuffer. |
| 179 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", | 156 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", |
| 180 TRACE_EVENT_SCOPE_GLOBAL); | 157 TRACE_EVENT_SCOPE_GLOBAL); |
| 181 } | 158 } |
| 182 | 159 |
| 183 DrawingBuffer::~DrawingBuffer() { | 160 DrawingBuffer::~DrawingBuffer() { |
| 184 DCHECK(m_destructionInProgress); | 161 DCHECK(m_destructionInProgress); |
| 185 m_layer.reset(); | 162 m_layer.reset(); |
| 186 m_contextProvider.reset(); | 163 m_contextProvider.reset(); |
| 187 } | 164 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 | 198 |
| 222 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { | 199 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { |
| 223 if (m_filterQuality != filterQuality) { | 200 if (m_filterQuality != filterQuality) { |
| 224 m_filterQuality = filterQuality; | 201 m_filterQuality = filterQuality; |
| 225 if (m_layer) | 202 if (m_layer) |
| 226 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 203 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); |
| 227 } | 204 } |
| 228 } | 205 } |
| 229 | 206 |
| 230 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { | 207 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { |
| 231 return !m_drawFramebufferBinding && | 208 return m_client->DrawingBufferClientIsBoundForDraw() && |
| 232 defaultBufferRequiresAlphaChannelToBePreserved(); | 209 defaultBufferRequiresAlphaChannelToBePreserved(); |
| 233 } | 210 } |
| 234 | 211 |
| 235 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { | 212 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { |
| 236 if (wantExplicitResolve()) { | 213 if (wantExplicitResolve()) { |
| 237 return !m_wantAlphaChannel && | 214 return !m_wantAlphaChannel && |
| 238 getMultisampledRenderbufferFormat() == GL_RGBA8_OES; | 215 getMultisampledRenderbufferFormat() == GL_RGBA8_OES; |
| 239 } | 216 } |
| 240 | 217 |
| 241 bool rgbEmulation = | 218 bool rgbEmulation = |
| (...skipping 15 matching lines...) Expand all Loading... |
| 257 DCHECK(recycled.size == m_size); | 234 DCHECK(recycled.size == m_size); |
| 258 return std::move(recycled.bitmap); | 235 return std::move(recycled.bitmap); |
| 259 } | 236 } |
| 260 | 237 |
| 261 return Platform::current()->allocateSharedBitmap(m_size); | 238 return Platform::current()->allocateSharedBitmap(m_size); |
| 262 } | 239 } |
| 263 | 240 |
| 264 bool DrawingBuffer::PrepareTextureMailbox( | 241 bool DrawingBuffer::PrepareTextureMailbox( |
| 265 cc::TextureMailbox* outMailbox, | 242 cc::TextureMailbox* outMailbox, |
| 266 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 243 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { |
| 244 ScopedStateRestorer scopedStateRestorer(this); |
| 267 bool forceGpuResult = false; | 245 bool forceGpuResult = false; |
| 268 return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, | 246 return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, |
| 269 forceGpuResult); | 247 forceGpuResult); |
| 270 } | 248 } |
| 271 | 249 |
| 272 bool DrawingBuffer::prepareTextureMailboxInternal( | 250 bool DrawingBuffer::prepareTextureMailboxInternal( |
| 273 cc::TextureMailbox* outMailbox, | 251 cc::TextureMailbox* outMailbox, |
| 274 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 252 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, |
| 275 bool forceGpuResult) { | 253 bool forceGpuResult) { |
| 276 if (m_destructionInProgress) { | 254 if (m_destructionInProgress) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 291 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) | 269 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) |
| 292 return false; | 270 return false; |
| 293 | 271 |
| 294 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); | 272 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); |
| 295 | 273 |
| 296 if (m_newMailboxCallback) | 274 if (m_newMailboxCallback) |
| 297 (*m_newMailboxCallback)(); | 275 (*m_newMailboxCallback)(); |
| 298 | 276 |
| 299 // Resolve the multisampled buffer into m_backColorBuffer texture. | 277 // Resolve the multisampled buffer into m_backColorBuffer texture. |
| 300 if (m_antiAliasingMode != None) | 278 if (m_antiAliasingMode != None) |
| 301 commit(); | 279 resolveMultisampleFramebufferInternal(); |
| 302 | 280 |
| 303 if (m_softwareRendering && !forceGpuResult) { | 281 if (m_softwareRendering && !forceGpuResult) { |
| 304 return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); | 282 return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); |
| 305 } else { | 283 } else { |
| 306 return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); | 284 return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); |
| 307 } | 285 } |
| 308 } | 286 } |
| 309 | 287 |
| 310 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( | 288 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( |
| 311 cc::TextureMailbox* outMailbox, | 289 cc::TextureMailbox* outMailbox, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 336 WTF::passed(std::move(bitmap)), m_size); | 314 WTF::passed(std::move(bitmap)), m_size); |
| 337 *outReleaseCallback = | 315 *outReleaseCallback = |
| 338 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 316 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); |
| 339 return true; | 317 return true; |
| 340 } | 318 } |
| 341 | 319 |
| 342 bool DrawingBuffer::finishPrepareTextureMailboxGpu( | 320 bool DrawingBuffer::finishPrepareTextureMailboxGpu( |
| 343 cc::TextureMailbox* outMailbox, | 321 cc::TextureMailbox* outMailbox, |
| 344 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 322 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { |
| 345 if (m_webGLVersion > WebGL1) { | 323 if (m_webGLVersion > WebGL1) { |
| 324 m_stateRestorer->setPixelUnpackBufferBindingDirty(); |
| 346 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 325 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| 347 } | 326 } |
| 348 | 327 |
| 349 // We must restore the texture binding since creating new textures, | |
| 350 // consuming and producing mailboxes changes it. | |
| 351 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, | |
| 352 m_texture2DBinding); | |
| 353 | |
| 354 // Specify the buffer that we will put in the mailbox. | 328 // Specify the buffer that we will put in the mailbox. |
| 355 RefPtr<ColorBuffer> colorBufferForMailbox; | 329 RefPtr<ColorBuffer> colorBufferForMailbox; |
| 356 if (m_preserveDrawingBuffer == Discard) { | 330 if (m_preserveDrawingBuffer == Discard) { |
| 357 // If we can discard the backbuffer, send the old backbuffer directly | 331 // If we can discard the backbuffer, send the old backbuffer directly |
| 358 // into the mailbox, and allocate (or recycle) a new backbuffer. | 332 // into the mailbox, and allocate (or recycle) a new backbuffer. |
| 359 colorBufferForMailbox = m_backColorBuffer; | 333 colorBufferForMailbox = m_backColorBuffer; |
| 360 m_backColorBuffer = createOrRecycleColorBuffer(); | 334 m_backColorBuffer = createOrRecycleColorBuffer(); |
| 361 attachColorBufferToReadFramebuffer(); | 335 attachColorBufferToReadFramebuffer(); |
| 362 | 336 |
| 363 // Explicitly specify that m_fbo (which is now bound to the just-allocated | 337 // Explicitly specify that m_fbo (which is now bound to the just-allocated |
| 364 // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for | 338 // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for |
| 365 // tile-based GPU architectures. | 339 // tile-based GPU architectures. |
| 366 if (m_discardFramebufferSupported) { | 340 if (m_discardFramebufferSupported) { |
| 367 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 341 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, |
| 368 GL_STENCIL_ATTACHMENT}; | 342 GL_STENCIL_ATTACHMENT}; |
| 343 m_stateRestorer->setFramebufferBindingDirty(); |
| 369 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 344 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 370 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 345 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); |
| 371 } | 346 } |
| 372 } else { | 347 } else { |
| 373 // If we can't discard the backbuffer, create (or recycle) a buffer to put | 348 // If we can't discard the backbuffer, create (or recycle) a buffer to put |
| 374 // in the mailbox, and copy backbuffer's contents there. | 349 // in the mailbox, and copy backbuffer's contents there. |
| 375 colorBufferForMailbox = createOrRecycleColorBuffer(); | 350 colorBufferForMailbox = createOrRecycleColorBuffer(); |
| 376 m_gl->CopySubTextureCHROMIUM( | 351 m_gl->CopySubTextureCHROMIUM( |
| 377 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 352 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, |
| 378 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 353 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 406 // mailbox is released (and while the release callback is running). | 381 // mailbox is released (and while the release callback is running). |
| 407 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, | 382 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, |
| 408 RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 383 RefPtr<DrawingBuffer>(this), colorBufferForMailbox); |
| 409 *outReleaseCallback = cc::SingleReleaseCallback::Create( | 384 *outReleaseCallback = cc::SingleReleaseCallback::Create( |
| 410 convertToBaseCallback(std::move(func))); | 385 convertToBaseCallback(std::move(func))); |
| 411 } | 386 } |
| 412 | 387 |
| 413 // Point |m_frontColorBuffer| to the buffer that we are now presenting. | 388 // Point |m_frontColorBuffer| to the buffer that we are now presenting. |
| 414 m_frontColorBuffer = colorBufferForMailbox; | 389 m_frontColorBuffer = colorBufferForMailbox; |
| 415 | 390 |
| 416 // Restore any state that we may have dirtied, and update dirty bits. | |
| 417 restoreFramebufferBindings(); | |
| 418 restorePixelUnpackBufferBindings(); | |
| 419 m_contentsChanged = false; | 391 m_contentsChanged = false; |
| 420 setBufferClearNeeded(true); | 392 setBufferClearNeeded(true); |
| 421 return true; | 393 return true; |
| 422 } | 394 } |
| 423 | 395 |
| 424 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, | 396 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, |
| 425 const gpu::SyncToken& syncToken, | 397 const gpu::SyncToken& syncToken, |
| 426 bool lostResource) { | 398 bool lostResource) { |
| 427 // If the mailbox has been returned by the compositor then it is no | 399 // If the mailbox has been returned by the compositor then it is no |
| 428 // longer being presented, and so is no longer the front buffer. | 400 // longer being presented, and so is no longer the front buffer. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 457 bool lostResource) { | 429 bool lostResource) { |
| 458 DCHECK(!syncToken.HasData()); // No sync tokens for software resources. | 430 DCHECK(!syncToken.HasData()); // No sync tokens for software resources. |
| 459 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) | 431 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) |
| 460 return; // Just delete the bitmap. | 432 return; // Just delete the bitmap. |
| 461 | 433 |
| 462 RecycledBitmap recycled = {std::move(bitmap), m_size}; | 434 RecycledBitmap recycled = {std::move(bitmap), m_size}; |
| 463 m_recycledBitmaps.append(std::move(recycled)); | 435 m_recycledBitmaps.append(std::move(recycled)); |
| 464 } | 436 } |
| 465 | 437 |
| 466 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 438 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { |
| 439 ScopedStateRestorer scopedStateRestorer(this); |
| 440 |
| 467 // This can be null if the context is lost before the first call to | 441 // This can be null if the context is lost before the first call to |
| 468 // grContext(). | 442 // grContext(). |
| 469 GrContext* grContext = m_contextProvider->grContext(); | 443 GrContext* grContext = m_contextProvider->grContext(); |
| 470 | 444 |
| 471 cc::TextureMailbox textureMailbox; | 445 cc::TextureMailbox textureMailbox; |
| 472 std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 446 std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; |
| 473 bool success = false; | 447 bool success = false; |
| 474 if (grContext) { | 448 if (grContext) { |
| 475 bool forceGpuResult = true; | 449 bool forceGpuResult = true; |
| 476 success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, | 450 success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 GLuint imageId) | 584 GLuint imageId) |
| 611 : drawingBuffer(drawingBuffer), | 585 : drawingBuffer(drawingBuffer), |
| 612 parameters(parameters), | 586 parameters(parameters), |
| 613 size(size), | 587 size(size), |
| 614 textureId(textureId), | 588 textureId(textureId), |
| 615 imageId(imageId) { | 589 imageId(imageId) { |
| 616 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 590 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); |
| 617 } | 591 } |
| 618 | 592 |
| 619 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 593 DrawingBuffer::ColorBuffer::~ColorBuffer() { |
| 620 gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL(); | 594 gpu::gles2::GLES2Interface* gl = drawingBuffer->m_gl; |
| 621 if (receiveSyncToken.HasData()) | 595 if (receiveSyncToken.HasData()) |
| 622 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); | 596 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); |
| 623 if (imageId) { | 597 if (imageId) { |
| 624 gl->BindTexture(parameters.target, textureId); | 598 gl->BindTexture(parameters.target, textureId); |
| 625 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); | 599 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); |
| 626 gl->DestroyImageCHROMIUM(imageId); | 600 gl->DestroyImageCHROMIUM(imageId); |
| 601 switch (parameters.target) { |
| 602 case GL_TEXTURE_2D: |
| 603 // Restore the texture binding for GL_TEXTURE_2D, since the client will |
| 604 // expect the previous state. |
| 605 if (drawingBuffer->m_client) |
| 606 drawingBuffer->m_client->DrawingBufferClientRestoreTexture2DBinding(); |
| 607 break; |
| 608 case GC3D_TEXTURE_RECTANGLE_ARB: |
| 609 // Rectangle textures aren't exposed to WebGL, so don't bother |
| 610 // restoring this state (there is no meaningful way to restore it). |
| 611 break; |
| 612 default: |
| 613 NOTREACHED(); |
| 614 break; |
| 615 } |
| 627 } | 616 } |
| 628 gl->DeleteTextures(1, &textureId); | 617 gl->DeleteTextures(1, &textureId); |
| 629 } | 618 } |
| 630 | 619 |
| 631 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { | 620 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { |
| 621 ScopedStateRestorer scopedStateRestorer(this); |
| 622 |
| 632 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 623 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 633 // Need to try to restore the context again later. | 624 // Need to try to restore the context again later. |
| 634 return false; | 625 return false; |
| 635 } | 626 } |
| 636 | 627 |
| 637 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 628 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); |
| 638 | 629 |
| 639 int maxSampleCount = 0; | 630 int maxSampleCount = 0; |
| 640 m_antiAliasingMode = None; | 631 m_antiAliasingMode = None; |
| 641 if (useMultisampling) { | 632 if (useMultisampling) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 653 // The Linux ATI bot fails | 644 // The Linux ATI bot fails |
| 654 // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage | 645 // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage |
| 655 // textures only if ScreenSpaceAntialiasing is enabled, because | 646 // textures only if ScreenSpaceAntialiasing is enabled, because |
| 656 // ScreenSpaceAntialiasing is much faster with storage textures. | 647 // ScreenSpaceAntialiasing is much faster with storage textures. |
| 657 m_storageTextureSupported = | 648 m_storageTextureSupported = |
| 658 (m_webGLVersion > WebGL1 || | 649 (m_webGLVersion > WebGL1 || |
| 659 m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && | 650 m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && |
| 660 m_antiAliasingMode == ScreenSpaceAntialiasing; | 651 m_antiAliasingMode == ScreenSpaceAntialiasing; |
| 661 m_sampleCount = std::min(4, maxSampleCount); | 652 m_sampleCount = std::min(4, maxSampleCount); |
| 662 | 653 |
| 654 m_stateRestorer->setFramebufferBindingDirty(); |
| 663 m_gl->GenFramebuffers(1, &m_fbo); | 655 m_gl->GenFramebuffers(1, &m_fbo); |
| 664 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 656 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 665 if (wantExplicitResolve()) { | 657 if (wantExplicitResolve()) { |
| 666 m_gl->GenFramebuffers(1, &m_multisampleFBO); | 658 m_gl->GenFramebuffers(1, &m_multisampleFBO); |
| 667 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 659 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 668 m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); | 660 m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); |
| 669 } | 661 } |
| 670 if (!reset(size)) | 662 if (!resizeFramebufferInternal(size)) |
| 671 return false; | 663 return false; |
| 672 | 664 |
| 673 if (m_depthStencilBuffer) { | 665 if (m_depthStencilBuffer) { |
| 674 DCHECK(wantDepthOrStencil()); | 666 DCHECK(wantDepthOrStencil()); |
| 675 m_hasImplicitStencilBuffer = !m_wantStencil; | 667 m_hasImplicitStencilBuffer = !m_wantStencil; |
| 676 } | 668 } |
| 677 | 669 |
| 678 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 670 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 679 // It's possible that the drawing buffer allocation provokes a context loss, | 671 // It's possible that the drawing buffer allocation provokes a context loss, |
| 680 // so check again just in case. http://crbug.com/512302 | 672 // so check again just in case. http://crbug.com/512302 |
| 681 return false; | 673 return false; |
| 682 } | 674 } |
| 683 | 675 |
| 684 return true; | 676 return true; |
| 685 } | 677 } |
| 686 | 678 |
| 687 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, | 679 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, |
| 688 GLuint texture, | 680 GLuint texture, |
| 689 GLenum internalFormat, | 681 GLenum internalFormat, |
| 690 GLenum destType, | 682 GLenum destType, |
| 691 GLint level, | 683 GLint level, |
| 692 bool premultiplyAlpha, | 684 bool premultiplyAlpha, |
| 693 bool flipY, | 685 bool flipY, |
| 694 SourceDrawingBuffer sourceBuffer) { | 686 SourceDrawingBuffer sourceBuffer) { |
| 687 ScopedStateRestorer scopedStateRestorer(this); |
| 688 |
| 695 if (m_contentsChanged) { | 689 if (m_contentsChanged) { |
| 696 if (m_antiAliasingMode != None) { | 690 if (m_antiAliasingMode != None) |
| 697 commit(); | 691 resolveMultisampleFramebufferInternal(); |
| 698 restoreFramebufferBindings(); | |
| 699 } | |
| 700 m_gl->Flush(); | 692 m_gl->Flush(); |
| 701 } | 693 } |
| 702 | 694 |
| 703 // Assume that the destination target is GL_TEXTURE_2D. | 695 // Assume that the destination target is GL_TEXTURE_2D. |
| 704 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( | 696 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( |
| 705 GL_TEXTURE_2D, internalFormat, destType, level)) | 697 GL_TEXTURE_2D, internalFormat, destType, level)) |
| 706 return false; | 698 return false; |
| 707 | 699 |
| 708 // Contexts may be in a different share group. We must transfer the texture | 700 // Contexts may be in a different share group. We must transfer the texture |
| 709 // through a mailbox first. | 701 // through a mailbox first. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 737 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); |
| 746 | 738 |
| 747 gl->Flush(); | 739 gl->Flush(); |
| 748 gpu::SyncToken syncToken; | 740 gpu::SyncToken syncToken; |
| 749 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 741 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); |
| 750 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); | 742 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); |
| 751 | 743 |
| 752 return true; | 744 return true; |
| 753 } | 745 } |
| 754 | 746 |
| 755 GLuint DrawingBuffer::framebuffer() const { | |
| 756 return m_fbo; | |
| 757 } | |
| 758 | |
| 759 WebLayer* DrawingBuffer::platformLayer() { | 747 WebLayer* DrawingBuffer::platformLayer() { |
| 760 if (!m_layer) { | 748 if (!m_layer) { |
| 761 m_layer = | 749 m_layer = |
| 762 Platform::current()->compositorSupport()->createExternalTextureLayer( | 750 Platform::current()->compositorSupport()->createExternalTextureLayer( |
| 763 this); | 751 this); |
| 764 | 752 |
| 765 m_layer->setOpaque(!m_wantAlphaChannel); | 753 m_layer->setOpaque(!m_wantAlphaChannel); |
| 766 m_layer->setBlendBackgroundColor(m_wantAlphaChannel); | 754 m_layer->setBlendBackgroundColor(m_wantAlphaChannel); |
| 767 m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 755 m_layer->setPremultipliedAlpha(m_premultipliedAlpha); |
| 768 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 756 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 | 790 |
| 803 m_backColorBuffer = nullptr; | 791 m_backColorBuffer = nullptr; |
| 804 m_frontColorBuffer = nullptr; | 792 m_frontColorBuffer = nullptr; |
| 805 m_multisampleRenderbuffer = 0; | 793 m_multisampleRenderbuffer = 0; |
| 806 m_depthStencilBuffer = 0; | 794 m_depthStencilBuffer = 0; |
| 807 m_multisampleFBO = 0; | 795 m_multisampleFBO = 0; |
| 808 m_fbo = 0; | 796 m_fbo = 0; |
| 809 | 797 |
| 810 if (m_layer) | 798 if (m_layer) |
| 811 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 799 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); |
| 800 |
| 801 m_client = nullptr; |
| 812 } | 802 } |
| 813 | 803 |
| 814 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 804 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { |
| 815 // Recreate m_backColorBuffer. | 805 // Recreate m_backColorBuffer. |
| 816 m_backColorBuffer = createColorBuffer(size); | 806 m_backColorBuffer = createColorBuffer(size); |
| 817 | 807 |
| 818 attachColorBufferToReadFramebuffer(); | 808 attachColorBufferToReadFramebuffer(); |
| 819 | 809 |
| 820 if (wantExplicitResolve()) { | 810 if (wantExplicitResolve()) { |
| 811 m_stateRestorer->setFramebufferBindingDirty(); |
| 812 m_stateRestorer->setRenderbufferBindingDirty(); |
| 821 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 813 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 822 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); | 814 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); |
| 823 m_gl->RenderbufferStorageMultisampleCHROMIUM( | 815 m_gl->RenderbufferStorageMultisampleCHROMIUM( |
| 824 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), | 816 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), |
| 825 size.width(), size.height()); | 817 size.width(), size.height()); |
| 826 | 818 |
| 827 if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 819 if (m_gl->GetError() == GL_OUT_OF_MEMORY) |
| 828 return false; | 820 return false; |
| 829 | 821 |
| 830 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 822 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 831 GL_RENDERBUFFER, m_multisampleRenderbuffer); | 823 GL_RENDERBUFFER, m_multisampleRenderbuffer); |
| 832 } | 824 } |
| 833 | 825 |
| 834 if (wantDepthOrStencil()) { | 826 if (wantDepthOrStencil()) { |
| 827 m_stateRestorer->setFramebufferBindingDirty(); |
| 828 m_stateRestorer->setRenderbufferBindingDirty(); |
| 835 m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 829 m_gl->BindFramebuffer(GL_FRAMEBUFFER, |
| 836 m_multisampleFBO ? m_multisampleFBO : m_fbo); | 830 m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 837 if (!m_depthStencilBuffer) | 831 if (!m_depthStencilBuffer) |
| 838 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 832 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); |
| 839 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 833 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); |
| 840 if (m_antiAliasingMode == MSAAImplicitResolve) { | 834 if (m_antiAliasingMode == MSAAImplicitResolve) { |
| 841 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, | 835 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, |
| 842 GL_DEPTH24_STENCIL8_OES, | 836 GL_DEPTH24_STENCIL8_OES, |
| 843 size.width(), size.height()); | 837 size.width(), size.height()); |
| 844 } else if (m_antiAliasingMode == MSAAExplicitResolve) { | 838 } else if (m_antiAliasingMode == MSAAExplicitResolve) { |
| 845 m_gl->RenderbufferStorageMultisampleCHROMIUM( | 839 m_gl->RenderbufferStorageMultisampleCHROMIUM( |
| 846 GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), | 840 GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), |
| 847 size.height()); | 841 size.height()); |
| 848 } else { | 842 } else { |
| 849 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, | 843 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, |
| 850 size.width(), size.height()); | 844 size.width(), size.height()); |
| 851 } | 845 } |
| 852 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we | 846 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we |
| 853 // emulate | 847 // emulate |
| 854 // it at the command buffer level for WebGL contexts. | 848 // it at the command buffer level for WebGL contexts. |
| 855 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, | 849 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, |
| 856 GL_RENDERBUFFER, m_depthStencilBuffer); | 850 GL_RENDERBUFFER, m_depthStencilBuffer); |
| 857 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 851 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); |
| 858 } | 852 } |
| 859 | 853 |
| 860 if (wantExplicitResolve()) { | 854 if (wantExplicitResolve()) { |
| 855 m_stateRestorer->setFramebufferBindingDirty(); |
| 861 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 856 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); |
| 862 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 857 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| 863 return false; | 858 return false; |
| 864 } | 859 } |
| 865 | 860 |
| 861 m_stateRestorer->setFramebufferBindingDirty(); |
| 866 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 862 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 867 return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == | 863 return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == |
| 868 GL_FRAMEBUFFER_COMPLETE; | 864 GL_FRAMEBUFFER_COMPLETE; |
| 869 } | 865 } |
| 870 | 866 |
| 871 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { | 867 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { |
| 868 ScopedStateRestorer scopedStateRestorer(this); |
| 869 clearFramebuffersInternal(clearMask); |
| 870 } |
| 871 |
| 872 void DrawingBuffer::clearFramebuffersInternal(GLbitfield clearMask) { |
| 873 m_stateRestorer->setFramebufferBindingDirty(); |
| 872 // We will clear the multisample FBO, but we also need to clear the | 874 // We will clear the multisample FBO, but we also need to clear the |
| 873 // non-multisampled buffer. | 875 // non-multisampled buffer. |
| 874 if (m_multisampleFBO) { | 876 if (m_multisampleFBO) { |
| 875 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 877 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 876 m_gl->Clear(GL_COLOR_BUFFER_BIT); | 878 m_gl->Clear(GL_COLOR_BUFFER_BIT); |
| 877 } | 879 } |
| 878 | 880 |
| 879 m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 881 m_gl->BindFramebuffer(GL_FRAMEBUFFER, |
| 880 m_multisampleFBO ? m_multisampleFBO : m_fbo); | 882 m_multisampleFBO ? m_multisampleFBO : m_fbo); |
| 881 m_gl->Clear(clearMask); | 883 m_gl->Clear(clearMask); |
| 882 } | 884 } |
| 883 | 885 |
| 884 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, | 886 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, |
| 885 const IntSize& curSize, | 887 const IntSize& curSize, |
| 886 int maxTextureSize) { | 888 int maxTextureSize) { |
| 887 IntSize adjustedSize = desiredSize; | 889 IntSize adjustedSize = desiredSize; |
| 888 | 890 |
| 889 // Clamp if the desired size is greater than the maximum texture size for the | 891 // Clamp if the desired size is greater than the maximum texture size for the |
| 890 // device. | 892 // device. |
| 891 if (adjustedSize.height() > maxTextureSize) | 893 if (adjustedSize.height() > maxTextureSize) |
| 892 adjustedSize.setHeight(maxTextureSize); | 894 adjustedSize.setHeight(maxTextureSize); |
| 893 | 895 |
| 894 if (adjustedSize.width() > maxTextureSize) | 896 if (adjustedSize.width() > maxTextureSize) |
| 895 adjustedSize.setWidth(maxTextureSize); | 897 adjustedSize.setWidth(maxTextureSize); |
| 896 | 898 |
| 897 return adjustedSize; | 899 return adjustedSize; |
| 898 } | 900 } |
| 899 | 901 |
| 900 bool DrawingBuffer::reset(const IntSize& newSize) { | 902 bool DrawingBuffer::resize(const IntSize& newSize) { |
| 903 ScopedStateRestorer scopedStateRestorer(this); |
| 904 return resizeFramebufferInternal(newSize); |
| 905 } |
| 906 |
| 907 bool DrawingBuffer::resizeFramebufferInternal(const IntSize& newSize) { |
| 901 CHECK(!newSize.isEmpty()); | 908 CHECK(!newSize.isEmpty()); |
| 902 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 909 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); |
| 903 if (adjustedSize.isEmpty()) | 910 if (adjustedSize.isEmpty()) |
| 904 return false; | 911 return false; |
| 905 | 912 |
| 906 if (adjustedSize != m_size) { | 913 if (adjustedSize != m_size) { |
| 907 do { | 914 do { |
| 908 if (!resizeDefaultFramebuffer(adjustedSize)) { | 915 if (!resizeDefaultFramebuffer(adjustedSize)) { |
| 909 adjustedSize.scale(s_resourceAdjustedRatio); | 916 adjustedSize.scale(s_resourceAdjustedRatio); |
| 910 continue; | 917 continue; |
| 911 } | 918 } |
| 912 break; | 919 break; |
| 913 } while (!adjustedSize.isEmpty()); | 920 } while (!adjustedSize.isEmpty()); |
| 914 | 921 |
| 915 m_size = adjustedSize; | 922 m_size = adjustedSize; |
| 916 // Free all mailboxes, because they are now of the wrong size. Only the | 923 // Free all mailboxes, because they are now of the wrong size. Only the |
| 917 // first call in this loop has any effect. | 924 // first call in this loop has any effect. |
| 918 m_recycledColorBufferQueue.clear(); | 925 m_recycledColorBufferQueue.clear(); |
| 919 m_recycledBitmaps.clear(); | 926 m_recycledBitmaps.clear(); |
| 920 | 927 |
| 921 if (adjustedSize.isEmpty()) | 928 if (adjustedSize.isEmpty()) |
| 922 return false; | 929 return false; |
| 923 } | 930 } |
| 924 | 931 |
| 932 m_stateRestorer->setClearStateDirty(); |
| 925 m_gl->Disable(GL_SCISSOR_TEST); | 933 m_gl->Disable(GL_SCISSOR_TEST); |
| 926 m_gl->ClearColor(0, 0, 0, | 934 m_gl->ClearColor(0, 0, 0, |
| 927 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); | 935 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); |
| 928 m_gl->ColorMask(true, true, true, true); | 936 m_gl->ColorMask(true, true, true, true); |
| 929 | 937 |
| 930 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 938 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; |
| 931 if (!!m_depthStencilBuffer) { | 939 if (!!m_depthStencilBuffer) { |
| 932 m_gl->ClearDepthf(1.0f); | 940 m_gl->ClearDepthf(1.0f); |
| 933 clearMask |= GL_DEPTH_BUFFER_BIT; | 941 clearMask |= GL_DEPTH_BUFFER_BIT; |
| 934 m_gl->DepthMask(true); | 942 m_gl->DepthMask(true); |
| 935 } | 943 } |
| 936 if (!!m_depthStencilBuffer) { | 944 if (!!m_depthStencilBuffer) { |
| 937 m_gl->ClearStencil(0); | 945 m_gl->ClearStencil(0); |
| 938 clearMask |= GL_STENCIL_BUFFER_BIT; | 946 clearMask |= GL_STENCIL_BUFFER_BIT; |
| 939 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 947 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); |
| 940 } | 948 } |
| 941 | 949 |
| 942 clearFramebuffers(clearMask); | 950 clearFramebuffersInternal(clearMask); |
| 943 return true; | 951 return true; |
| 944 } | 952 } |
| 945 | 953 |
| 946 void DrawingBuffer::commit() { | 954 void DrawingBuffer::resolveAndBindForReadAndDraw() { |
| 955 { |
| 956 ScopedStateRestorer scopedStateRestorer(this); |
| 957 resolveMultisampleFramebufferInternal(); |
| 958 } |
| 959 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 960 } |
| 961 |
| 962 void DrawingBuffer::resolveMultisampleFramebufferInternal() { |
| 963 m_stateRestorer->setFramebufferBindingDirty(); |
| 947 if (wantExplicitResolve() && !m_contentsChangeCommitted) { | 964 if (wantExplicitResolve() && !m_contentsChangeCommitted) { |
| 965 m_stateRestorer->setClearStateDirty(); |
| 948 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 966 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); |
| 949 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 967 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); |
| 950 | 968 m_gl->Disable(GL_SCISSOR_TEST); |
| 951 if (m_scissorEnabled) | |
| 952 m_gl->Disable(GL_SCISSOR_TEST); | |
| 953 | 969 |
| 954 int width = m_size.width(); | 970 int width = m_size.width(); |
| 955 int height = m_size.height(); | 971 int height = m_size.height(); |
| 956 // Use NEAREST, because there is no scale performed during the blit. | 972 // Use NEAREST, because there is no scale performed during the blit. |
| 957 GLuint filter = GL_NEAREST; | 973 GLuint filter = GL_NEAREST; |
| 958 | 974 |
| 959 m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, | 975 m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, |
| 960 GL_COLOR_BUFFER_BIT, filter); | 976 GL_COLOR_BUFFER_BIT, filter); |
| 961 | 977 |
| 962 // On old AMD GPUs on OS X, glColorMask doesn't work correctly for | 978 // On old AMD GPUs on OS X, glColorMask doesn't work correctly for |
| 963 // multisampled renderbuffers and the alpha channel can be overwritten. | 979 // multisampled renderbuffers and the alpha channel can be overwritten. |
| 964 // Clear the alpha channel of |m_fbo|. | 980 // Clear the alpha channel of |m_fbo|. |
| 965 if (defaultBufferRequiresAlphaChannelToBePreserved() && | 981 if (defaultBufferRequiresAlphaChannelToBePreserved() && |
| 966 contextProvider() | 982 contextProvider() |
| 967 ->getCapabilities() | 983 ->getCapabilities() |
| 968 .disable_multisampling_color_mask_usage) { | 984 .disable_multisampling_color_mask_usage) { |
| 969 m_gl->ClearColor(0, 0, 0, 1); | 985 m_gl->ClearColor(0, 0, 0, 1); |
| 970 m_gl->ColorMask(false, false, false, true); | 986 m_gl->ColorMask(false, false, false, true); |
| 971 m_gl->Clear(GL_COLOR_BUFFER_BIT); | |
| 972 | |
| 973 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], | |
| 974 m_clearColor[3]); | |
| 975 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], | |
| 976 m_colorMask[3]); | |
| 977 } | 987 } |
| 978 | |
| 979 if (m_scissorEnabled) | |
| 980 m_gl->Enable(GL_SCISSOR_TEST); | |
| 981 } | 988 } |
| 982 | 989 |
| 983 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 990 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 984 if (m_antiAliasingMode == ScreenSpaceAntialiasing) { | 991 if (m_antiAliasingMode == ScreenSpaceAntialiasing) |
| 985 m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); | 992 m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); |
| 986 } | |
| 987 m_contentsChangeCommitted = true; | 993 m_contentsChangeCommitted = true; |
| 988 } | 994 } |
| 989 | 995 |
| 990 void DrawingBuffer::restorePixelUnpackBufferBindings() { | 996 void DrawingBuffer::restoreFramebufferBindings() { |
| 991 if (m_webGLVersion > WebGL1) { | 997 m_client->DrawingBufferClientRestoreFramebufferBinding(); |
| 992 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixelUnpackBufferBinding); | |
| 993 } | |
| 994 } | 998 } |
| 995 | 999 |
| 996 void DrawingBuffer::restoreFramebufferBindings() { | 1000 void DrawingBuffer::restoreAllState() { |
| 997 if (m_drawFramebufferBinding && m_readFramebufferBinding) { | 1001 m_client->DrawingBufferClientRestoreScissorTest(); |
| 998 if (m_drawFramebufferBinding == m_readFramebufferBinding) { | 1002 m_client->DrawingBufferClientRestoreMaskAndClearValues(); |
| 999 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_readFramebufferBinding); | 1003 m_client->DrawingBufferClientRestorePixelPackAlignment(); |
| 1000 } else { | 1004 m_client->DrawingBufferClientRestoreTexture2DBinding(); |
| 1001 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); | 1005 m_client->DrawingBufferClientRestoreRenderbufferBinding(); |
| 1002 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); | 1006 m_client->DrawingBufferClientRestoreFramebufferBinding(); |
| 1003 } | 1007 m_client->DrawingBufferClientRestorePixelUnpackBufferBinding(); |
| 1004 return; | |
| 1005 } | |
| 1006 if (!m_drawFramebufferBinding && !m_readFramebufferBinding) { | |
| 1007 bind(GL_FRAMEBUFFER); | |
| 1008 return; | |
| 1009 } | |
| 1010 if (!m_drawFramebufferBinding) { | |
| 1011 bind(GL_DRAW_FRAMEBUFFER); | |
| 1012 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); | |
| 1013 } else { | |
| 1014 bind(GL_READ_FRAMEBUFFER); | |
| 1015 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); | |
| 1016 } | |
| 1017 } | 1008 } |
| 1018 | 1009 |
| 1019 bool DrawingBuffer::multisample() const { | 1010 bool DrawingBuffer::multisample() const { |
| 1020 return m_antiAliasingMode != None; | 1011 return m_antiAliasingMode != None; |
| 1021 } | 1012 } |
| 1022 | 1013 |
| 1023 void DrawingBuffer::bind(GLenum target) { | 1014 void DrawingBuffer::bind(GLenum target) { |
| 1024 m_gl->BindFramebuffer(target, | 1015 m_gl->BindFramebuffer(target, |
| 1025 wantExplicitResolve() ? m_multisampleFBO : m_fbo); | 1016 wantExplicitResolve() ? m_multisampleFBO : m_fbo); |
| 1026 } | 1017 } |
| 1027 | 1018 |
| 1028 void DrawingBuffer::setPackAlignment(GLint param) { | |
| 1029 m_packAlignment = param; | |
| 1030 } | |
| 1031 | |
| 1032 bool DrawingBuffer::paintRenderingResultsToImageData( | 1019 bool DrawingBuffer::paintRenderingResultsToImageData( |
| 1033 int& width, | 1020 int& width, |
| 1034 int& height, | 1021 int& height, |
| 1035 SourceDrawingBuffer sourceBuffer, | 1022 SourceDrawingBuffer sourceBuffer, |
| 1036 WTF::ArrayBufferContents& contents) { | 1023 WTF::ArrayBufferContents& contents) { |
| 1024 ScopedStateRestorer scopedStateRestorer(this); |
| 1025 |
| 1037 ASSERT(!m_premultipliedAlpha); | 1026 ASSERT(!m_premultipliedAlpha); |
| 1038 width = size().width(); | 1027 width = size().width(); |
| 1039 height = size().height(); | 1028 height = size().height(); |
| 1040 | 1029 |
| 1041 CheckedNumeric<int> dataSize = 4; | 1030 CheckedNumeric<int> dataSize = 4; |
| 1042 dataSize *= width; | 1031 dataSize *= width; |
| 1043 dataSize *= height; | 1032 dataSize *= height; |
| 1044 if (!dataSize.IsValid()) | 1033 if (!dataSize.IsValid()) |
| 1045 return false; | 1034 return false; |
| 1046 | 1035 |
| 1047 WTF::ArrayBufferContents pixels(width * height, 4, | 1036 WTF::ArrayBufferContents pixels(width * height, 4, |
| 1048 WTF::ArrayBufferContents::NotShared, | 1037 WTF::ArrayBufferContents::NotShared, |
| 1049 WTF::ArrayBufferContents::DontInitialize); | 1038 WTF::ArrayBufferContents::DontInitialize); |
| 1050 | 1039 |
| 1051 GLuint fbo = 0; | 1040 GLuint fbo = 0; |
| 1041 m_stateRestorer->setFramebufferBindingDirty(); |
| 1052 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { | 1042 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { |
| 1053 m_gl->GenFramebuffers(1, &fbo); | 1043 m_gl->GenFramebuffers(1, &fbo); |
| 1054 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 1044 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); |
| 1055 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1045 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 1056 m_frontColorBuffer->parameters.target, | 1046 m_frontColorBuffer->parameters.target, |
| 1057 m_frontColorBuffer->textureId, 0); | 1047 m_frontColorBuffer->textureId, 0); |
| 1058 } else { | 1048 } else { |
| 1059 m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer()); | 1049 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 1060 } | 1050 } |
| 1061 | 1051 |
| 1062 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, | 1052 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, |
| 1063 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); | 1053 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); |
| 1064 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); | 1054 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); |
| 1065 | 1055 |
| 1066 if (fbo) { | 1056 if (fbo) { |
| 1067 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1057 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 1068 m_frontColorBuffer->parameters.target, 0, 0); | 1058 m_frontColorBuffer->parameters.target, 0, 0); |
| 1069 m_gl->DeleteFramebuffers(1, &fbo); | 1059 m_gl->DeleteFramebuffers(1, &fbo); |
| 1070 } | 1060 } |
| 1071 | 1061 |
| 1072 restoreFramebufferBindings(); | |
| 1073 | |
| 1074 pixels.transfer(contents); | 1062 pixels.transfer(contents); |
| 1075 return true; | 1063 return true; |
| 1076 } | 1064 } |
| 1077 | 1065 |
| 1078 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 1066 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, |
| 1079 int width, | 1067 int width, |
| 1080 int height, | 1068 int height, |
| 1081 ReadbackOrder readbackOrder, | 1069 ReadbackOrder readbackOrder, |
| 1082 WebGLImageConversion::AlphaOp op) { | 1070 WebGLImageConversion::AlphaOp op) { |
| 1083 if (m_packAlignment > 4) | 1071 m_stateRestorer->setPixelPackAlignmentDirty(); |
| 1084 m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); | 1072 m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); |
| 1085 m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 1073 m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
| 1086 if (m_packAlignment > 4) | |
| 1087 m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_packAlignment); | |
| 1088 | 1074 |
| 1089 size_t bufferSize = 4 * width * height; | 1075 size_t bufferSize = 4 * width * height; |
| 1090 | 1076 |
| 1091 if (readbackOrder == ReadbackSkia) { | 1077 if (readbackOrder == ReadbackSkia) { |
| 1092 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 1078 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| 1093 // Swizzle red and blue channels to match SkBitmap's byte ordering. | 1079 // Swizzle red and blue channels to match SkBitmap's byte ordering. |
| 1094 // TODO(kbr): expose GL_BGRA as extension. | 1080 // TODO(kbr): expose GL_BGRA as extension. |
| 1095 for (size_t i = 0; i < bufferSize; i += 4) { | 1081 for (size_t i = 0; i < bufferSize; i += 4) { |
| 1096 std::swap(pixels[i], pixels[i + 2]); | 1082 std::swap(pixels[i], pixels[i + 2]); |
| 1097 } | 1083 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1119 uint8_t* rowA = framebuffer + i * rowBytes; | 1105 uint8_t* rowA = framebuffer + i * rowBytes; |
| 1120 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 1106 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; |
| 1121 memcpy(scanline.data(), rowB, rowBytes); | 1107 memcpy(scanline.data(), rowB, rowBytes); |
| 1122 memcpy(rowB, rowA, rowBytes); | 1108 memcpy(rowB, rowA, rowBytes); |
| 1123 memcpy(rowA, scanline.data(), rowBytes); | 1109 memcpy(rowA, scanline.data(), rowBytes); |
| 1124 } | 1110 } |
| 1125 } | 1111 } |
| 1126 | 1112 |
| 1127 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( | 1113 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( |
| 1128 const IntSize& size) { | 1114 const IntSize& size) { |
| 1115 m_stateRestorer->setFramebufferBindingDirty(); |
| 1116 m_stateRestorer->setTextureBindingDirty(); |
| 1117 |
| 1129 // Select the Parameters for the texture object. Allocate the backing | 1118 // Select the Parameters for the texture object. Allocate the backing |
| 1130 // GpuMemoryBuffer and GLImage, if one is going to be used. | 1119 // GpuMemoryBuffer and GLImage, if one is going to be used. |
| 1131 ColorBufferParameters parameters; | 1120 ColorBufferParameters parameters; |
| 1132 GLuint imageId = 0; | 1121 GLuint imageId = 0; |
| 1133 if (shouldUseChromiumImage()) { | 1122 if (shouldUseChromiumImage()) { |
| 1134 parameters = gpuMemoryBufferColorBufferParameters(); | 1123 parameters = gpuMemoryBufferColorBufferParameters(); |
| 1135 imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 1124 imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( |
| 1136 size.width(), size.height(), parameters.creationInternalColorFormat, | 1125 size.width(), size.height(), parameters.creationInternalColorFormat, |
| 1137 GC3D_SCANOUT_CHROMIUM); | 1126 GC3D_SCANOUT_CHROMIUM); |
| 1138 } else { | 1127 } else { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 parameters.creationInternalColorFormat, size.width(), | 1160 parameters.creationInternalColorFormat, size.width(), |
| 1172 size.height(), 0, parameters.colorFormat, | 1161 size.height(), 0, parameters.colorFormat, |
| 1173 GL_UNSIGNED_BYTE, 0); | 1162 GL_UNSIGNED_BYTE, 0); |
| 1174 } | 1163 } |
| 1175 } | 1164 } |
| 1176 | 1165 |
| 1177 // Clear the alpha channel if this is RGB emulated. | 1166 // Clear the alpha channel if this is RGB emulated. |
| 1178 if (imageId && !m_wantAlphaChannel && | 1167 if (imageId && !m_wantAlphaChannel && |
| 1179 contextProvider()->getCapabilities().chromium_image_rgb_emulation) { | 1168 contextProvider()->getCapabilities().chromium_image_rgb_emulation) { |
| 1180 GLuint fbo = 0; | 1169 GLuint fbo = 0; |
| 1170 |
| 1171 m_stateRestorer->setClearStateDirty(); |
| 1181 m_gl->GenFramebuffers(1, &fbo); | 1172 m_gl->GenFramebuffers(1, &fbo); |
| 1182 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 1173 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); |
| 1183 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1174 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 1184 parameters.target, textureId, 0); | 1175 parameters.target, textureId, 0); |
| 1185 m_gl->ClearColor(0, 0, 0, 1); | 1176 m_gl->ClearColor(0, 0, 0, 1); |
| 1186 m_gl->ColorMask(false, false, false, true); | 1177 m_gl->ColorMask(false, false, false, true); |
| 1187 m_gl->Clear(GL_COLOR_BUFFER_BIT); | 1178 m_gl->Clear(GL_COLOR_BUFFER_BIT); |
| 1188 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1179 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 1189 parameters.target, 0, 0); | 1180 parameters.target, 0, 0); |
| 1190 m_gl->DeleteFramebuffers(1, &fbo); | 1181 m_gl->DeleteFramebuffers(1, &fbo); |
| 1191 restoreFramebufferBindings(); | |
| 1192 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], | |
| 1193 m_clearColor[3]); | |
| 1194 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], | |
| 1195 m_colorMask[3]); | |
| 1196 } | 1182 } |
| 1197 | 1183 |
| 1198 return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); | 1184 return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); |
| 1199 } | 1185 } |
| 1200 | 1186 |
| 1201 void DrawingBuffer::attachColorBufferToReadFramebuffer() { | 1187 void DrawingBuffer::attachColorBufferToReadFramebuffer() { |
| 1188 m_stateRestorer->setFramebufferBindingDirty(); |
| 1189 m_stateRestorer->setTextureBindingDirty(); |
| 1190 |
| 1202 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 1191 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| 1203 | 1192 |
| 1204 GLenum target = m_backColorBuffer->parameters.target; | 1193 GLenum target = m_backColorBuffer->parameters.target; |
| 1205 GLenum id = m_backColorBuffer->textureId; | 1194 GLenum id = m_backColorBuffer->textureId; |
| 1206 | 1195 |
| 1207 m_gl->BindTexture(target, id); | 1196 m_gl->BindTexture(target, id); |
| 1208 | 1197 |
| 1209 if (m_antiAliasingMode == MSAAImplicitResolve) | 1198 if (m_antiAliasingMode == MSAAImplicitResolve) |
| 1210 m_gl->FramebufferTexture2DMultisampleEXT( | 1199 m_gl->FramebufferTexture2DMultisampleEXT( |
| 1211 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); | 1200 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); |
| 1212 else | 1201 else |
| 1213 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, | 1202 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, |
| 1214 0); | 1203 0); |
| 1215 | |
| 1216 restoreTextureBindings(); | |
| 1217 restoreFramebufferBindings(); | |
| 1218 } | 1204 } |
| 1219 | 1205 |
| 1220 bool DrawingBuffer::wantExplicitResolve() { | 1206 bool DrawingBuffer::wantExplicitResolve() { |
| 1221 return m_antiAliasingMode == MSAAExplicitResolve; | 1207 return m_antiAliasingMode == MSAAExplicitResolve; |
| 1222 } | 1208 } |
| 1223 | 1209 |
| 1224 bool DrawingBuffer::wantDepthOrStencil() { | 1210 bool DrawingBuffer::wantDepthOrStencil() { |
| 1225 return m_wantDepth || m_wantStencil; | 1211 return m_wantDepth || m_wantStencil; |
| 1226 } | 1212 } |
| 1227 | 1213 |
| 1228 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { | 1214 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { |
| 1229 DCHECK(wantExplicitResolve()); | 1215 DCHECK(wantExplicitResolve()); |
| 1230 if (m_wantAlphaChannel) | 1216 if (m_wantAlphaChannel) |
| 1231 return GL_RGBA8_OES; | 1217 return GL_RGBA8_OES; |
| 1232 if (shouldUseChromiumImage() && | 1218 if (shouldUseChromiumImage() && |
| 1233 contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 1219 contextProvider()->getCapabilities().chromium_image_rgb_emulation) |
| 1234 return GL_RGBA8_OES; | 1220 return GL_RGBA8_OES; |
| 1235 if (contextProvider() | 1221 if (contextProvider() |
| 1236 ->getCapabilities() | 1222 ->getCapabilities() |
| 1237 .disable_webgl_rgb_multisampling_usage) | 1223 .disable_webgl_rgb_multisampling_usage) |
| 1238 return GL_RGBA8_OES; | 1224 return GL_RGBA8_OES; |
| 1239 return GL_RGB8_OES; | 1225 return GL_RGB8_OES; |
| 1240 } | 1226 } |
| 1241 | 1227 |
| 1242 void DrawingBuffer::restoreTextureBindings() { | 1228 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer( |
| 1243 // This class potentially modifies the bindings for GL_TEXTURE_2D and | 1229 DrawingBuffer* drawingBuffer) |
| 1244 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since | 1230 : m_drawingBuffer(drawingBuffer) { |
| 1245 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. | 1231 DCHECK(!m_drawingBuffer->m_stateRestorer); |
| 1246 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); | 1232 m_drawingBuffer->m_stateRestorer = this; |
| 1233 } |
| 1234 |
| 1235 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { |
| 1236 m_drawingBuffer->m_stateRestorer = nullptr; |
| 1237 Client* client = m_drawingBuffer->m_client; |
| 1238 if (!client) |
| 1239 return; |
| 1240 |
| 1241 if (m_clearStateDirty) { |
| 1242 client->DrawingBufferClientRestoreScissorTest(); |
| 1243 client->DrawingBufferClientRestoreMaskAndClearValues(); |
| 1244 } |
| 1245 if (m_pixelPackAlignmentDirty) |
| 1246 client->DrawingBufferClientRestorePixelPackAlignment(); |
| 1247 if (m_textureBindingDirty) |
| 1248 client->DrawingBufferClientRestoreTexture2DBinding(); |
| 1249 if (m_renderbufferBindingDirty) |
| 1250 client->DrawingBufferClientRestoreRenderbufferBinding(); |
| 1251 if (m_framebufferBindingDirty) |
| 1252 client->DrawingBufferClientRestoreFramebufferBinding(); |
| 1253 if (m_pixelUnpackBufferBindingDirty) |
| 1254 client->DrawingBufferClientRestorePixelUnpackBufferBinding(); |
| 1247 } | 1255 } |
| 1248 | 1256 |
| 1249 bool DrawingBuffer::shouldUseChromiumImage() { | 1257 bool DrawingBuffer::shouldUseChromiumImage() { |
| 1250 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 1258 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && |
| 1251 m_chromiumImageUsage == AllowChromiumImage; | 1259 m_chromiumImageUsage == AllowChromiumImage; |
| 1252 } | 1260 } |
| 1253 | 1261 |
| 1254 } // namespace blink | 1262 } // namespace blink |
| OLD | NEW |