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

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