summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc')
-rw-r--r--chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc123
1 files changed, 61 insertions, 62 deletions
diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index d54fa99d5cb..65b672a3573 100644
--- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -253,6 +253,8 @@ void DrawingBuffer::SetIsHidden(bool hidden) {
is_hidden_ = hidden;
if (is_hidden_)
recycled_color_buffer_queue_.clear();
+ gl_->ContextVisibilityHintCHROMIUM(is_hidden_ ? GL_FALSE : GL_TRUE);
+ gl_->Flush();
}
void DrawingBuffer::SetFilterQuality(SkFilterQuality filter_quality) {
@@ -557,9 +559,10 @@ scoped_refptr<StaticBitmapImage> DrawingBuffer::TransferToStaticBitmapImage(
// to transferToImageBitmap are made back-to-back, or when the context gets
// lost. We intentionally leave the transparent black image in legacy color
// space.
- sk_sp<SkSurface> surface =
- SkSurface::MakeRasterN32Premul(size_.Width(), size_.Height());
- return StaticBitmapImage::Create(surface->makeImageSnapshot());
+ SkBitmap black_bitmap;
+ black_bitmap.allocN32Pixels(size_.Width(), size_.Height());
+ black_bitmap.eraseARGB(0, 0, 0, 0);
+ return StaticBitmapImage::Create(SkImage::MakeFromBitmap(black_bitmap));
}
DCHECK_EQ(size_.Width(), transferable_resource.size.width());
@@ -670,12 +673,11 @@ DrawingBuffer::ColorBuffer::~ColorBuffer() {
sii->DestroySharedImage(receive_sync_token, mailbox);
gpu_memory_buffer.reset();
- gl->DeleteTextures(1, &texture_id);
- if (rgb_workaround_texture_id) {
- sii->DestroySharedImage(receive_sync_token, rgb_workaround_mailbox);
- // Avoid deleting this texture if it was unused.
- gl->DeleteTextures(1, &rgb_workaround_texture_id);
- }
+ gl->DeleteTextures(1u, &texture_id);
+
+ // Avoid deleting this texture if it was unused.
+ if (rgb_workaround_texture_id)
+ gl->DeleteTextures(1u, &rgb_workaround_texture_id);
}
bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
@@ -810,16 +812,6 @@ bool DrawingBuffer::Initialize(const IntSize& size, bool use_multisampling) {
allocate_alpha_channel_ = false;
have_alpha_channel_ = true;
}
- if (UsingSwapChain()) {
- // Swap chains always have an alpha channel, and multisample resolve
- // doesn't work if we pretend we don't have one.
- // This configuration will
- // - allow invalid CopyTexImage to RGBA targets
- // - fail valid FramebufferBlit from RGB targets
- // TODO(sunnyps): Copy into intermediate texture for blitFramebuffer.
- allocate_alpha_channel_ = true;
- have_alpha_channel_ = true;
- }
}
state_restorer_->SetFramebufferBindingDirty();
@@ -1071,33 +1063,9 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) {
AttachColorBufferToReadFramebuffer();
if (WantExplicitResolve()) {
- state_restorer_->SetFramebufferBindingDirty();
- state_restorer_->SetRenderbufferBindingDirty();
- gl_->BindFramebuffer(GL_FRAMEBUFFER, multisample_fbo_);
- gl_->BindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_);
- // Note that the multisample rendertarget will allocate an alpha channel
- // based on |have_alpha_channel_|, not |allocate_alpha_channel_|, since it
- // will resolve into the ColorBuffer.
- GLenum internal_format = have_alpha_channel_ ? GL_RGBA8_OES : GL_RGB8_OES;
- if (use_half_float_storage_) {
- DCHECK(want_alpha_channel_);
- internal_format = GL_RGBA16F_EXT;
- }
- if (has_eqaa_support) {
- gl_->RenderbufferStorageMultisampleAdvancedAMD(
- GL_RENDERBUFFER, sample_count_, eqaa_storage_sample_count_,
- internal_format, size.Width(), size.Height());
- } else {
- gl_->RenderbufferStorageMultisampleCHROMIUM(
- GL_RENDERBUFFER, sample_count_, internal_format, size.Width(),
- size.Height());
- }
-
- if (gl_->GetError() == GL_OUT_OF_MEMORY)
+ if (!ReallocateMultisampleRenderbuffer(size)) {
return false;
-
- gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_RENDERBUFFER, multisample_renderbuffer_);
+ }
}
if (WantDepthOrStencil()) {
@@ -1276,6 +1244,47 @@ void DrawingBuffer::ResolveIfNeeded() {
!contents_change_resolved_)
ResolveMultisampleFramebufferInternal();
contents_change_resolved_ = true;
+
+ auto* gl = ContextProvider()->ContextGL();
+ if (gl->DidGpuSwitch() == GL_TRUE) {
+ // TODO(crbug.com/681341): handle preserveDrawingBuffer:true, and
+ // user-allocated multisampled renderbuffers, by dispatching a context lost
+ // event.
+ if (WantExplicitResolve()) {
+ ReallocateMultisampleRenderbuffer(size_);
+ }
+ }
+}
+
+bool DrawingBuffer::ReallocateMultisampleRenderbuffer(const IntSize& size) {
+ state_restorer_->SetFramebufferBindingDirty();
+ state_restorer_->SetRenderbufferBindingDirty();
+ gl_->BindFramebuffer(GL_FRAMEBUFFER, multisample_fbo_);
+ gl_->BindRenderbuffer(GL_RENDERBUFFER, multisample_renderbuffer_);
+ // Note that the multisample rendertarget will allocate an alpha channel
+ // based on |have_alpha_channel_|, not |allocate_alpha_channel_|, since it
+ // will resolve into the ColorBuffer.
+ GLenum internal_format = have_alpha_channel_ ? GL_RGBA8_OES : GL_RGB8_OES;
+ if (use_half_float_storage_) {
+ DCHECK(want_alpha_channel_);
+ internal_format = GL_RGBA16F_EXT;
+ }
+ if (has_eqaa_support) {
+ gl_->RenderbufferStorageMultisampleAdvancedAMD(
+ GL_RENDERBUFFER, sample_count_, eqaa_storage_sample_count_,
+ internal_format, size.Width(), size.Height());
+ } else {
+ gl_->RenderbufferStorageMultisampleCHROMIUM(GL_RENDERBUFFER, sample_count_,
+ internal_format, size.Width(),
+ size.Height());
+ }
+
+ if (gl_->GetError() == GL_OUT_OF_MEMORY)
+ return false;
+
+ gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_RENDERBUFFER, multisample_renderbuffer_);
+ return true;
}
void DrawingBuffer::RestoreFramebufferBindings() {
@@ -1301,7 +1310,7 @@ void DrawingBuffer::Bind(GLenum target) {
gl_->BindFramebuffer(target, WantExplicitResolve() ? multisample_fbo_ : fbo_);
}
-scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray(
+sk_sp<SkData> DrawingBuffer::PaintRenderingResultsToDataArray(
SourceDrawingBuffer source_buffer) {
ScopedStateRestorer scoped_state_restorer(this);
@@ -1318,19 +1327,10 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray(
if (!data_size.IsValid())
return nullptr;
- unsigned byte_length = width * height * 4;
- if (RuntimeEnabledFeatures::CanvasColorManagementEnabled() &&
- use_half_float_storage_) {
- byte_length *= 2;
- }
- scoped_refptr<ArrayBuffer> dst_buffer =
- ArrayBuffer::CreateOrNull(byte_length, 1);
+ unsigned byte_length = data_size.ValueOrDie<unsigned>();
+ sk_sp<SkData> dst_buffer = TryAllocateSkData(byte_length);
if (!dst_buffer)
return nullptr;
- scoped_refptr<Uint8Array> data_array =
- Uint8Array::Create(std::move(dst_buffer), 0, byte_length);
- if (!data_array)
- return nullptr;
GLuint fbo = 0;
state_restorer_->SetFramebufferBindingDirty();
@@ -1344,10 +1344,10 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray(
gl_->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
}
- ReadBackFramebuffer(static_cast<unsigned char*>(data_array->Data()), width,
- height, kReadbackRGBA,
+ auto* writable_data = static_cast<uint8_t*>(dst_buffer->writable_data());
+ ReadBackFramebuffer(writable_data, width, height, kReadbackRGBA,
WebGLImageConversion::kAlphaDoNothing);
- FlipVertically(static_cast<uint8_t*>(data_array->Data()), width, height);
+ FlipVertically(writable_data, width, height);
if (fbo) {
gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
@@ -1355,7 +1355,7 @@ scoped_refptr<Uint8Array> DrawingBuffer::PaintRenderingResultsToDataArray(
gl_->DeleteFramebuffers(1, &fbo);
}
- return data_array;
+ return dst_buffer;
}
void DrawingBuffer::ReadBackFramebuffer(unsigned char* pixels,
@@ -1502,7 +1502,6 @@ scoped_refptr<DrawingBuffer::ColorBuffer> DrawingBuffer::CreateColorBuffer(
format = use_half_float_storage_ ? viz::RGBA_F16 : viz::RGBA_8888;
} else {
DCHECK(!use_half_float_storage_);
- DCHECK(!UsingSwapChain());
format = viz::RGBX_8888;
}