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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
index 155558732ef1c1bfd811b51a7aaa3b5d72de3334..d4f384554dc9c51736d3c58b20f7f35ee702cc70 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -576,6 +576,19 @@ DrawingBuffer::CreateOrRecycleColorBuffer() {
return CreateColorBuffer(size_);
}
+DrawingBuffer::ScopedRGBEmulationForBlitFramebuffer::
+ ScopedRGBEmulationForBlitFramebuffer(DrawingBuffer* drawing_buffer)
+ : drawing_buffer_(drawing_buffer) {
+ doing_work_ = drawing_buffer->SetupRGBEmulationForBlitFramebuffer();
+}
+
+DrawingBuffer::ScopedRGBEmulationForBlitFramebuffer::
+ ~ScopedRGBEmulationForBlitFramebuffer() {
+ if (doing_work_) {
+ drawing_buffer_->CleanupRGBEmulationForBlitFramebuffer();
+ }
+}
+
DrawingBuffer::ColorBuffer::ColorBuffer(
DrawingBuffer* drawing_buffer,
const ColorBufferParameters& parameters,
@@ -599,6 +612,10 @@ DrawingBuffer::ColorBuffer::~ColorBuffer() {
if (image_id) {
gl->BindTexture(parameters.target, texture_id);
gl->ReleaseTexImage2DCHROMIUM(parameters.target, image_id);
+ if (rgb_workaround_texture_id) {
+ gl->BindTexture(parameters.target, rgb_workaround_texture_id);
+ gl->ReleaseTexImage2DCHROMIUM(parameters.target, image_id);
+ }
gl->DestroyImageCHROMIUM(image_id);
switch (parameters.target) {
case GL_TEXTURE_2D:
@@ -618,6 +635,7 @@ DrawingBuffer::ColorBuffer::~ColorBuffer() {
gpu_memory_buffer.reset();
}
gl->DeleteTextures(1, &texture_id);
+ gl->DeleteTextures(1, &rgb_workaround_texture_id);
}
bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
@@ -1258,6 +1276,78 @@ GLenum DrawingBuffer::GetMultisampledRenderbufferFormat() {
return GL_RGB8_OES;
}
+bool DrawingBuffer::SetupRGBEmulationForBlitFramebuffer() {
+ // We only need to do this work if:
+ // - The user has selected alpha:false and antialias:false
+ // - We are using CHROMIUM_image with RGB emulation
+ // macOS is the only platform on which this is necessary.
+
+ if (want_alpha_channel_ || anti_aliasing_mode_ != kNone)
+ return false;
+
+ if (!(ShouldUseChromiumImage() &&
+ ContextProvider()->GetCapabilities().chromium_image_rgb_emulation))
+ return false;
+
+ if (!back_color_buffer_)
+ return false;
+
+ // If for some reason the back buffer doesn't have a CHROMIUM_image,
+ // don't proceed with this workaround.
+ if (!back_color_buffer_->image_id)
+ return false;
+
+ // Before allowing the BlitFramebuffer call to go through, it's necessary
+ // to swap out the RGBA texture that's bound to the CHROMIUM_image
+ // instance with an RGB texture. BlitFramebuffer requires the internal
+ // formats of the source and destination to match when doing a
+ // multisample resolve, and the best way to achieve this without adding
+ // more full-screen blits is to hook up a true RGB texture to the
+ // underlying IOSurface. Unfortunately, on macOS, this rendering path
+ // destroys the alpha channel and requires a fixup afterward, which is
+ // why it isn't used all the time.
+
+ GLuint rgb_texture = back_color_buffer_->rgb_workaround_texture_id;
+ GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
+ if (!rgb_texture) {
+ gl_->GenTextures(1, &rgb_texture);
+ gl_->BindTexture(target, rgb_texture);
+ gl_->TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl_->TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl_->TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl_->TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ // Bind this texture to the CHROMIUM_image instance that the color
+ // buffer owns. This is an expensive operation, so it's important that
+ // the result be cached.
+ gl_->BindTexImage2DWithInternalformatCHROMIUM(target, GL_RGB,
+ back_color_buffer_->image_id);
+ back_color_buffer_->rgb_workaround_texture_id = rgb_texture;
+ }
+
+ gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0,
+ target, rgb_texture, 0);
+ return true;
+}
+
+void DrawingBuffer::CleanupRGBEmulationForBlitFramebuffer() {
+ // This will only be called if SetupRGBEmulationForBlitFramebuffer was.
+ // Put the framebuffer back the way it was, and clear the alpha channel.
+ DCHECK(back_color_buffer_);
+ DCHECK(back_color_buffer_->image_id);
+ GLenum target = GC3D_TEXTURE_RECTANGLE_ARB;
+ gl_->FramebufferTexture2D(GL_DRAW_FRAMEBUFFER_ANGLE, GL_COLOR_ATTACHMENT0,
+ target, back_color_buffer_->texture_id, 0);
+ // Clear the alpha channel.
+ gl_->ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
+ gl_->Disable(GL_SCISSOR_TEST);
+ gl_->ClearColor(0, 0, 0, 1);
+ gl_->Clear(GL_COLOR_BUFFER_BIT);
+ DCHECK(client_);
+ client_->DrawingBufferClientRestoreScissorTest();
+ client_->DrawingBufferClientRestoreMaskAndClearValues();
+}
+
DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer(
DrawingBuffer* drawing_buffer)
: drawing_buffer_(drawing_buffer) {
« 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