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