Commit 12180c59 authored by shrekshao's avatar shrekshao Committed by Commit Bot

Reallocate multisample_renderbuffer when GPU switching

This is a temporary patch that is not well refactored but seems to make the following case work properly:
* Init webgl context with low-power gpu, switch tab to one using high-power, and switch back. It renders correctly now before the os switch back to low-power.

This patch doesn't work with:
* Same tab switching case where user allocated multisampled buffer under a webgl 2 context
* Same tab switching case with preseverDrawingbuffer: true.

We'd better land this patch after the gpu pixel test is landed.

Bug: 681341
Change-Id: I9c834d11ee0456545600819f2322dceb38f8a59a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1812102Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Commit-Queue: Shrek Shao <shrekshao@google.com>
Cr-Commit-Position: refs/heads/master@{#703425}
parent a9663272
...@@ -1063,33 +1063,9 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) { ...@@ -1063,33 +1063,9 @@ bool DrawingBuffer::ResizeDefaultFramebuffer(const IntSize& size) {
AttachColorBufferToReadFramebuffer(); AttachColorBufferToReadFramebuffer();
if (WantExplicitResolve()) { if (WantExplicitResolve()) {
state_restorer_->SetFramebufferBindingDirty(); if (!ReallocateMultisampleRenderbuffer(size)) {
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; return false;
}
gl_->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, multisample_renderbuffer_);
} }
if (WantDepthOrStencil()) { if (WantDepthOrStencil()) {
...@@ -1271,10 +1247,46 @@ void DrawingBuffer::ResolveIfNeeded() { ...@@ -1271,10 +1247,46 @@ void DrawingBuffer::ResolveIfNeeded() {
auto* gl = ContextProvider()->ContextGL(); auto* gl = ContextProvider()->ContextGL();
if (gl->DidGpuSwitch() == GL_TRUE) { if (gl->DidGpuSwitch() == GL_TRUE) {
// TODO(crbug.com/681341): reallocate multi-sampled render buffer. // 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() { void DrawingBuffer::RestoreFramebufferBindings() {
client_->DrawingBufferClientRestoreFramebufferBinding(); client_->DrawingBufferClientRestoreFramebufferBinding();
} }
......
...@@ -474,6 +474,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, ...@@ -474,6 +474,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient,
bool SetupRGBEmulationForBlitFramebuffer(bool is_user_draw_framebuffer_bound); bool SetupRGBEmulationForBlitFramebuffer(bool is_user_draw_framebuffer_bound);
void CleanupRGBEmulationForBlitFramebuffer(); void CleanupRGBEmulationForBlitFramebuffer();
// Reallocate Multisampled renderbuffer, used by explicit resolve when resize
// and GPU switch
bool ReallocateMultisampleRenderbuffer(const IntSize&);
// Weak, reset by beginDestruction. // Weak, reset by beginDestruction.
Client* client_ = nullptr; Client* client_ = nullptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment