Commit a1b0e0df authored by skyostil@chromium.org's avatar skyostil@chromium.org

cc: Invalidate framebuffer contents when clearing

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
parent 4714d682
......@@ -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
......@@ -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();
};
......
......@@ -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())
......@@ -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)
......
......@@ -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) {
......@@ -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) {
......@@ -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
......
......@@ -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() {}
......
......@@ -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 {
......
......@@ -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;
}
......
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