Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(770)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp

Issue 2831733003: Fix blits from multisampled renderbuffers to alpha:false WebGL back buffer. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h ('k') | ui/gl/gl_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h ('k') | ui/gl/gl_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698