Chromium Code Reviews| 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 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 if (!recycled_color_buffer_queue_.IsEmpty()) { | 582 if (!recycled_color_buffer_queue_.IsEmpty()) { |
| 583 RefPtr<ColorBuffer> recycled = recycled_color_buffer_queue_.TakeLast(); | 583 RefPtr<ColorBuffer> recycled = recycled_color_buffer_queue_.TakeLast(); |
| 584 if (recycled->receive_sync_token.HasData()) | 584 if (recycled->receive_sync_token.HasData()) |
| 585 gl_->WaitSyncTokenCHROMIUM(recycled->receive_sync_token.GetData()); | 585 gl_->WaitSyncTokenCHROMIUM(recycled->receive_sync_token.GetData()); |
| 586 DCHECK(recycled->size == size_); | 586 DCHECK(recycled->size == size_); |
| 587 return recycled; | 587 return recycled; |
| 588 } | 588 } |
| 589 return CreateColorBuffer(size_); | 589 return CreateColorBuffer(size_); |
| 590 } | 590 } |
| 591 | 591 |
| 592 DrawingBuffer::ScopedRGBEmulationForBlitFramebuffer:: | |
| 593 ScopedRGBEmulationForBlitFramebuffer(DrawingBuffer* drawing_buffer) | |
| 594 : drawing_buffer_(drawing_buffer) { | |
| 595 doing_work_ = drawing_buffer->SetupRGBEmulationForBlitFramebuffer(); | |
| 596 } | |
| 597 | |
| 598 DrawingBuffer::ScopedRGBEmulationForBlitFramebuffer:: | |
| 599 ~ScopedRGBEmulationForBlitFramebuffer() { | |
| 600 if (doing_work_) { | |
| 601 drawing_buffer_->CleanupRGBEmulationForBlitFramebuffer(); | |
| 602 } | |
| 603 } | |
| 604 | |
| 592 DrawingBuffer::ColorBuffer::ColorBuffer( | 605 DrawingBuffer::ColorBuffer::ColorBuffer( |
| 593 DrawingBuffer* drawing_buffer, | 606 DrawingBuffer* drawing_buffer, |
| 594 const ColorBufferParameters& parameters, | 607 const ColorBufferParameters& parameters, |
| 595 const IntSize& size, | 608 const IntSize& size, |
| 596 GLuint texture_id, | 609 GLuint texture_id, |
| 597 GLuint image_id, | 610 GLuint image_id, |
| 598 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer) | 611 std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer) |
| 599 : drawing_buffer(drawing_buffer), | 612 : drawing_buffer(drawing_buffer), |
| 600 parameters(parameters), | 613 parameters(parameters), |
| 601 size(size), | 614 size(size), |
| 602 texture_id(texture_id), | 615 texture_id(texture_id), |
| 603 image_id(image_id), | 616 image_id(image_id), |
| 604 gpu_memory_buffer(std::move(gpu_memory_buffer)) { | 617 gpu_memory_buffer(std::move(gpu_memory_buffer)) { |
| 605 drawing_buffer->ContextGL()->GenMailboxCHROMIUM(mailbox.name); | 618 drawing_buffer->ContextGL()->GenMailboxCHROMIUM(mailbox.name); |
| 606 } | 619 } |
| 607 | 620 |
| 608 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 621 DrawingBuffer::ColorBuffer::~ColorBuffer() { |
| 609 gpu::gles2::GLES2Interface* gl = drawing_buffer->gl_; | 622 gpu::gles2::GLES2Interface* gl = drawing_buffer->gl_; |
| 610 if (receive_sync_token.HasData()) | 623 if (receive_sync_token.HasData()) |
| 611 gl->WaitSyncTokenCHROMIUM(receive_sync_token.GetConstData()); | 624 gl->WaitSyncTokenCHROMIUM(receive_sync_token.GetConstData()); |
| 612 if (image_id) { | 625 if (image_id) { |
| 613 gl->BindTexture(parameters.target, texture_id); | 626 gl->BindTexture(parameters.target, texture_id); |
| 614 gl->ReleaseTexImage2DCHROMIUM(parameters.target, image_id); | 627 gl->ReleaseTexImage2DCHROMIUM(parameters.target, image_id); |
| 628 if (rgb_workaround_texture_id) { | |
| 629 gl->BindTexture(parameters.target, rgb_workaround_texture_id); | |
| 630 gl->ReleaseTexImage2DCHROMIUM(parameters.target, image_id); | |
| 631 } | |
| 615 gl->DestroyImageCHROMIUM(image_id); | 632 gl->DestroyImageCHROMIUM(image_id); |
| 616 switch (parameters.target) { | 633 switch (parameters.target) { |
| 617 case GL_TEXTURE_2D: | 634 case GL_TEXTURE_2D: |
| 618 // Restore the texture binding for GL_TEXTURE_2D, since the client will | 635 // Restore the texture binding for GL_TEXTURE_2D, since the client will |
| 619 // expect the previous state. | 636 // expect the previous state. |
| 620 if (drawing_buffer->client_) | 637 if (drawing_buffer->client_) |
| 621 drawing_buffer->client_->DrawingBufferClientRestoreTexture2DBinding(); | 638 drawing_buffer->client_->DrawingBufferClientRestoreTexture2DBinding(); |
| 622 break; | 639 break; |
| 623 case GC3D_TEXTURE_RECTANGLE_ARB: | 640 case GC3D_TEXTURE_RECTANGLE_ARB: |
| 624 // Rectangle textures aren't exposed to WebGL, so don't bother | 641 // Rectangle textures aren't exposed to WebGL, so don't bother |
| 625 // restoring this state (there is no meaningful way to restore it). | 642 // restoring this state (there is no meaningful way to restore it). |
| 626 break; | 643 break; |
| 627 default: | 644 default: |
| 628 NOTREACHED(); | 645 NOTREACHED(); |
| 629 break; | 646 break; |
| 630 } | 647 } |
| 631 gpu_memory_buffer.reset(); | 648 gpu_memory_buffer.reset(); |
| 632 } | 649 } |
| 633 gl->DeleteTextures(1, &texture_id); | 650 gl->DeleteTextures(1, &texture_id); |
| 651 gl->DeleteTextures(1, &rgb_workaround_texture_id); | |
| 634 } | 652 } |
| 635 | 653 |
| 636 bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) { | 654 bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) { |
| 637 ScopedStateRestorer scoped_state_restorer(this); | 655 ScopedStateRestorer scoped_state_restorer(this); |
| 638 | 656 |
| 639 if (gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 657 if (gl_->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { |
| 640 // Need to try to restore the context again later. | 658 // Need to try to restore the context again later. |
| 641 return false; | 659 return false; |
| 642 } | 660 } |
| 643 | 661 |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1264 if (ShouldUseChromiumImage() && | 1282 if (ShouldUseChromiumImage() && |
| 1265 ContextProvider()->GetCapabilities().chromium_image_rgb_emulation) | 1283 ContextProvider()->GetCapabilities().chromium_image_rgb_emulation) |
| 1266 return GL_RGBA8_OES; | 1284 return GL_RGBA8_OES; |
| 1267 if (ContextProvider() | 1285 if (ContextProvider() |
| 1268 ->GetCapabilities() | 1286 ->GetCapabilities() |
| 1269 .disable_webgl_rgb_multisampling_usage) | 1287 .disable_webgl_rgb_multisampling_usage) |
| 1270 return GL_RGBA8_OES; | 1288 return GL_RGBA8_OES; |
| 1271 return GL_RGB8_OES; | 1289 return GL_RGB8_OES; |
| 1272 } | 1290 } |
| 1273 | 1291 |
| 1292 bool DrawingBuffer::SetupRGBEmulationForBlitFramebuffer() { | |
| 1293 // We only need to do this work if: | |
| 1294 // - The user has selected alpha:false and antialias:false | |
| 1295 // - We are using CHROMIUM_image with RGB emulation | |
| 1296 // macOS is the only platform on which this is necessary. | |
| 1297 | |
| 1298 if (want_alpha_channel_ || anti_aliasing_mode_ != kNone) | |
| 1299 return false; | |
| 1300 | |
| 1301 if (!(ShouldUseChromiumImage() && | |
| 1302 ContextProvider()->GetCapabilities().chromium_image_rgb_emulation)) | |
| 1303 return false; | |
| 1304 | |
| 1305 if (!back_color_buffer_) | |
| 1306 return false; | |
| 1307 | |
| 1308 // If for some reason the back buffer doesn't have a CHROMIUM_image, | |
| 1309 // don't proceed with this workaround. | |
| 1310 if (!back_color_buffer_->image_id) | |
| 1311 return false; | |
| 1312 | |
| 1313 // Before allowing the BlitFramebuffer call to go through, it's necessary | |
| 1314 // to swap out the RGBA texture that's bound to the CHROMIUM_image | |
| 1315 // instance with an RGB texture. BlitFramebuffer requires the internal | |
| 1316 // formats of the source and destination to match when doing a | |
| 1317 // multisample resolve, and the best way to achieve this without adding | |
| 1318 // more full-screen blits is to hook up a true RGB texture to the | |
| 1319 // underlying IOSurface. Unfortunately, on macOS, this rendering path | |
| 1320 // destroys the alpha channel and requires a fixup afterward, which is | |
| 1321 // why it isn't used all the time. | |
| 1322 | |
| 1323 GLuint rgb_texture = back_color_buffer_->rgb_workaround_texture_id; | |
| 1324 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB; | |
| 1325 if (!rgb_texture) { | |
| 1326 gl_->GenTextures(1, &rgb_texture); | |
| 1327 gl_->BindTexture(target, rgb_texture); | |
| 1328 gl_->TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 1329 gl_->TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 1330 gl_->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 1331 gl_->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 1332 | |
| 1333 // Bind this texture to the CHROMIUM_image instance that the color | |
| 1334 // buffer owns. This is an expensive operation, so it's important that | |
| 1335 // the result be cached. | |
| 1336 gl_->BindTexImage2DWithInternalformatCHROMIUM(target, GL_RGB, | |
| 1337 back_color_buffer_->image_id); | |
| 1338 back_color_buffer_->rgb_workaround_texture_id = rgb_texture; | |
| 1339 } | |
| 1340 | |
| 1341 gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0, | |
| 1342 target, rgb_texture, 0); | |
| 1343 return true; | |
| 1344 } | |
| 1345 | |
| 1346 void DrawingBuffer::CleanupRGBEmulationForBlitFramebuffer() { | |
| 1347 // This will only be called if SetupRGBEmulationForBlitFramebuffer was. | |
| 1348 // Put the framebuffer back the way it was, and clear the alpha channel. | |
| 1349 DCHECK(back_color_buffer_); | |
| 1350 DCHECK(back_color_buffer_->image_id); | |
| 1351 GLenum target = GC3D_TEXTURE_RECTANGLE_ARB; | |
| 1352 gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0, | |
| 1353 target, back_color_buffer_->texture_id, 0); | |
|
Zhenyao Mo
2017/04/19 23:07:34
Please make sure this was bound before SetupRGBEmu
Ken Russell (switch to Gerrit)
2017/04/20 01:49:18
Confirmed that it is, in AttachColorBufferToReadFr
| |
| 1354 // Clear the alpha channel. | |
| 1355 gl_->ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); | |
| 1356 gl_->Disable(GL_SCISSOR_TEST); | |
| 1357 gl_->ClearColor(0, 0, 0, 1); | |
| 1358 gl_->Clear(GL_COLOR_BUFFER_BIT); | |
| 1359 DCHECK(client_); | |
| 1360 client_->DrawingBufferClientRestoreScissorTest(); | |
| 1361 client_->DrawingBufferClientRestoreMaskAndClearValues(); | |
| 1362 } | |
| 1363 | |
| 1274 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer( | 1364 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer( |
| 1275 DrawingBuffer* drawing_buffer) | 1365 DrawingBuffer* drawing_buffer) |
| 1276 : drawing_buffer_(drawing_buffer) { | 1366 : drawing_buffer_(drawing_buffer) { |
| 1277 // If this is a nested restorer, save the previous restorer. | 1367 // If this is a nested restorer, save the previous restorer. |
| 1278 previous_state_restorer_ = drawing_buffer->state_restorer_; | 1368 previous_state_restorer_ = drawing_buffer->state_restorer_; |
| 1279 drawing_buffer_->state_restorer_ = this; | 1369 drawing_buffer_->state_restorer_ = this; |
| 1280 } | 1370 } |
| 1281 | 1371 |
| 1282 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { | 1372 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { |
| 1283 DCHECK_EQ(drawing_buffer_->state_restorer_, this); | 1373 DCHECK_EQ(drawing_buffer_->state_restorer_, this); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1301 if (pixel_unpack_buffer_binding_dirty_) | 1391 if (pixel_unpack_buffer_binding_dirty_) |
| 1302 client->DrawingBufferClientRestorePixelUnpackBufferBinding(); | 1392 client->DrawingBufferClientRestorePixelUnpackBufferBinding(); |
| 1303 } | 1393 } |
| 1304 | 1394 |
| 1305 bool DrawingBuffer::ShouldUseChromiumImage() { | 1395 bool DrawingBuffer::ShouldUseChromiumImage() { |
| 1306 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 1396 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && |
| 1307 chromium_image_usage_ == kAllowChromiumImage; | 1397 chromium_image_usage_ == kAllowChromiumImage; |
| 1308 } | 1398 } |
| 1309 | 1399 |
| 1310 } // namespace blink | 1400 } // namespace blink |
| OLD | NEW |