Skip to content

Commit

Permalink
cc: Invalidate framebuffer contents when clearing
Browse files Browse the repository at this point in the history
When clearing the contents of a framebuffer, also invalidate/discard it
if the GL implementation supports this functionality. This improves
performance especially on tiling architecture GPUs since the graphics
driver does not need to restore the previous contents of the framebuffer
before proceeding with rendering.

Note that normally we don't clear the contents of framebuffers whose
contents we know we will completely re-render. This patch will still
invalidate such framebuffers to let the driver know that the previous
contents are not relevant.

BUG=274334

Review URL: https://chromiumcodereview.appspot.com/23601013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221425 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
skyostil@chromium.org committed Sep 5, 2013
1 parent 4714d68 commit a1b0e0d
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 14 deletions.
3 changes: 2 additions & 1 deletion cc/output/context_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ContextProvider::Capabilities::Capabilities()
texture_format_bgra8888(false),
texture_rectangle(false),
texture_storage(false),
texture_usage(false) {}
texture_usage(false),
discard_framebuffer(false) {}

} // namespace cc
1 change: 1 addition & 0 deletions cc/output/context_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
bool texture_rectangle;
bool texture_storage;
bool texture_usage;
bool discard_framebuffer;

CC_EXPORT Capabilities();
};
Expand Down
11 changes: 11 additions & 0 deletions cc/output/gl_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ bool GLRenderer::Initialize() {
capabilities_.using_map_image =
Settings().use_map_image && context_caps.map_image;

capabilities_.using_discard_framebuffer =
context_caps.discard_framebuffer;

is_using_bind_uniform_ = context_caps.bind_uniform_location;

if (!InitializeSharedObjects())
Expand Down Expand Up @@ -293,6 +296,14 @@ void GLRenderer::ClearFramebuffer(DrawingFrame* frame) {
return;
}

if (capabilities_.using_discard_framebuffer) {
GLenum attachments[] = {
GL_COLOR_EXT
};
context_->discardFramebufferEXT(
GL_FRAMEBUFFER, arraysize(attachments), attachments);
}

// On DEBUG builds, opaque render passes are cleared to blue to easily see
// regions that were not drawn on the screen.
if (frame->current_render_pass->has_transparent_background)
Expand Down
30 changes: 18 additions & 12 deletions cc/output/gl_renderer_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -702,14 +702,15 @@ TEST(GLRendererTest2, InitializationWithQuicklyLostContextDoesNotAssert) {

class ClearCountingContext : public TestWebGraphicsContext3D {
public:
ClearCountingContext() : clear_(0) {}

virtual void clear(WGC3Dbitfield) { clear_++; }

int clear_count() const { return clear_; }
ClearCountingContext() {
test_capabilities_.discard_framebuffer = true;
}

private:
int clear_;
MOCK_METHOD3(discardFramebufferEXT,
void(WGC3Denum target,
WGC3Dsizei numAttachments,
const WGC3Denum* attachments));
MOCK_METHOD1(clear, void(WGC3Dbitfield mask));
};

TEST(GLRendererTest2, OpaqueBackground) {
Expand All @@ -732,15 +733,17 @@ TEST(GLRendererTest2, OpaqueBackground) {

EXPECT_TRUE(renderer.Initialize());

renderer.DrawFrame(renderer_client.render_passes_in_draw_order(), NULL);

// On DEBUG builds, render passes with opaque background clear to blue to
// easily see regions that were not drawn on the screen.
EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _))
.Times(1);
#ifdef NDEBUG
EXPECT_EQ(0, context->clear_count());
EXPECT_CALL(*context, clear(_)).Times(0);
#else
EXPECT_EQ(1, context->clear_count());
EXPECT_CALL(*context, clear(_)).Times(1);
#endif
renderer.DrawFrame(renderer_client.render_passes_in_draw_order(), NULL);
Mock::VerifyAndClearExpectations(context);
}

TEST(GLRendererTest2, TransparentBackground) {
Expand All @@ -763,9 +766,12 @@ TEST(GLRendererTest2, TransparentBackground) {

EXPECT_TRUE(renderer.Initialize());

EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _))
.Times(1);
EXPECT_CALL(*context, clear(_)).Times(1);
renderer.DrawFrame(renderer_client.render_passes_in_draw_order(), NULL);

EXPECT_EQ(1, context->clear_count());
Mock::VerifyAndClearExpectations(context);
}

class VisibilityChangeIsLastCallTrackingContext
Expand Down
3 changes: 2 additions & 1 deletion cc/trees/layer_tree_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ RendererCapabilities::RendererCapabilities()
max_texture_size(0),
avoid_pow2_textures(false),
using_map_image(false),
using_shared_memory_resources(false) {}
using_shared_memory_resources(false),
using_discard_framebuffer(false) {}

RendererCapabilities::~RendererCapabilities() {}

Expand Down
1 change: 1 addition & 0 deletions cc/trees/layer_tree_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct CC_EXPORT RendererCapabilities {
bool avoid_pow2_textures;
bool using_map_image;
bool using_shared_memory_resources;
bool using_discard_framebuffer;
};

struct CC_EXPORT UIResourceRequest {
Expand Down
3 changes: 3 additions & 0 deletions content/common/gpu/client/context_provider_command_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ void ContextProviderCommandBuffer::InitializeCapabilities() {
caps.texture_usage = extension_set.count("GL_ANGLE_texture_usage") > 0;
caps.texture_storage = extension_set.count("GL_EXT_texture_storage") > 0;

caps.discard_framebuffer =
extension_set.count("GL_EXT_discard_framebuffer") > 0;

capabilities_ = caps;
}

Expand Down

0 comments on commit a1b0e0d

Please sign in to comment.