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

Side by Side Diff: cc/output/gl_renderer_unittest.cc

Issue 24239006: cc: Don't discard framebuffer when using partial swaps (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/output/gl_renderer.h" 5 #include "cc/output/gl_renderer.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "cc/base/math_util.h" 9 #include "cc/base/math_util.h"
10 #include "cc/debug/test_web_graphics_context_3d.h" 10 #include "cc/debug/test_web_graphics_context_3d.h"
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 private: 136 private:
137 int frame_; 137 int frame_;
138 }; 138 };
139 139
140 class FakeRendererClient : public RendererClient { 140 class FakeRendererClient : public RendererClient {
141 public: 141 public:
142 FakeRendererClient() 142 FakeRendererClient()
143 : host_impl_(&proxy_), 143 : host_impl_(&proxy_),
144 set_full_root_layer_damage_count_(0), 144 set_full_root_layer_damage_count_(0),
145 root_layer_(LayerImpl::Create(host_impl_.active_tree(), 1)), 145 root_layer_(LayerImpl::Create(host_impl_.active_tree(), 1)),
146 viewport_size_(gfx::Size(1, 1)) { 146 viewport_(gfx::Rect(0, 0, 1, 1)),
147 clip_(gfx::Rect(0, 0, 1, 1)) {
147 root_layer_->CreateRenderSurface(); 148 root_layer_->CreateRenderSurface();
148 RenderPass::Id render_pass_id = 149 RenderPass::Id render_pass_id =
149 root_layer_->render_surface()->RenderPassId(); 150 root_layer_->render_surface()->RenderPassId();
150 scoped_ptr<RenderPass> root_render_pass = RenderPass::Create(); 151 scoped_ptr<RenderPass> root_render_pass = RenderPass::Create();
151 root_render_pass->SetNew( 152 root_render_pass->SetNew(
152 render_pass_id, gfx::Rect(), gfx::Rect(), gfx::Transform()); 153 render_pass_id, gfx::Rect(), gfx::Rect(), gfx::Transform());
153 render_passes_in_draw_order_.push_back(root_render_pass.Pass()); 154 render_passes_in_draw_order_.push_back(root_render_pass.Pass());
154 } 155 }
155 156
156 // RendererClient methods. 157 // RendererClient methods.
157 virtual gfx::Rect DeviceViewport() const OVERRIDE { 158 virtual gfx::Rect DeviceViewport() const OVERRIDE {
158 static gfx::Size fake_size(1, 1); 159 return viewport_;
159 return gfx::Rect(fake_size);
160 } 160 }
161 virtual gfx::Rect DeviceClip() const OVERRIDE { return DeviceViewport(); } 161 virtual gfx::Rect DeviceClip() const OVERRIDE {
162 return clip_;
163 }
162 virtual void SetFullRootLayerDamage() OVERRIDE { 164 virtual void SetFullRootLayerDamage() OVERRIDE {
163 set_full_root_layer_damage_count_++; 165 set_full_root_layer_damage_count_++;
164 } 166 }
165 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE { 167 virtual CompositorFrameMetadata MakeCompositorFrameMetadata() const OVERRIDE {
166 return CompositorFrameMetadata(); 168 return CompositorFrameMetadata();
167 } 169 }
168 170
169 // Methods added for test. 171 // Methods added for test.
170 int set_full_root_layer_damage_count() const { 172 int set_full_root_layer_damage_count() const {
171 return set_full_root_layer_damage_count_; 173 return set_full_root_layer_damage_count_;
172 } 174 }
173 void set_viewport(gfx::Size viewport_size) { viewport_size_ = viewport_size; } 175 void set_viewport(gfx::Rect viewport) { viewport_ = viewport; }
176 void set_clip(gfx::Rect clip) { clip_ = clip; }
174 177
175 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); } 178 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
176 RenderPassList* render_passes_in_draw_order() { 179 RenderPassList* render_passes_in_draw_order() {
177 return &render_passes_in_draw_order_; 180 return &render_passes_in_draw_order_;
178 } 181 }
179 182
180 private: 183 private:
181 FakeImplProxy proxy_; 184 FakeImplProxy proxy_;
182 FakeLayerTreeHostImpl host_impl_; 185 FakeLayerTreeHostImpl host_impl_;
183 int set_full_root_layer_damage_count_; 186 int set_full_root_layer_damage_count_;
184 scoped_ptr<LayerImpl> root_layer_; 187 scoped_ptr<LayerImpl> root_layer_;
185 RenderPassList render_passes_in_draw_order_; 188 RenderPassList render_passes_in_draw_order_;
186 gfx::Size viewport_size_; 189 gfx::Rect viewport_;
190 gfx::Rect clip_;
187 }; 191 };
188 192
189 class FakeRendererGL : public GLRenderer { 193 class FakeRendererGL : public GLRenderer {
190 public: 194 public:
191 FakeRendererGL(RendererClient* client, 195 FakeRendererGL(RendererClient* client,
192 const LayerTreeSettings* settings, 196 const LayerTreeSettings* settings,
193 OutputSurface* output_surface, 197 OutputSurface* output_surface,
194 ResourceProvider* resource_provider) 198 ResourceProvider* resource_provider)
195 : GLRenderer(client, 199 : GLRenderer(client,
196 settings, 200 settings,
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 1134
1131 AddRenderPassQuad(root_pass, child_pass); 1135 AddRenderPassQuad(root_pass, child_pass);
1132 AddRenderPassQuad(child_pass, grand_child_pass); 1136 AddRenderPassQuad(child_pass, grand_child_pass);
1133 1137
1134 renderer.DecideRenderPassAllocationsForFrame( 1138 renderer.DecideRenderPassAllocationsForFrame(
1135 *renderer_client.render_passes_in_draw_order()); 1139 *renderer_client.render_passes_in_draw_order());
1136 renderer.DrawFrame( 1140 renderer.DrawFrame(
1137 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true); 1141 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1138 } 1142 }
1139 1143
1144 class DiscardCheckingContext : public TestWebGraphicsContext3D {
1145 public:
1146 DiscardCheckingContext() : discarded_(0) {
1147 set_have_post_sub_buffer(true);
1148 set_have_discard_framebuffer(true);
1149 }
1150
1151 virtual void discardFramebufferEXT(WGC3Denum target,
1152 WGC3Dsizei numAttachments,
1153 const WGC3Denum* attachments) {
1154 ++discarded_;
1155 }
1156
1157 int discarded() const { return discarded_; }
1158 void reset() { discarded_ = 0; }
1159
1160 private:
1161 int discarded_;
1162 };
1163
1140 class NonReshapableOutputSurface : public FakeOutputSurface { 1164 class NonReshapableOutputSurface : public FakeOutputSurface {
1141 public: 1165 public:
1142 explicit NonReshapableOutputSurface( 1166 explicit NonReshapableOutputSurface(
1143 scoped_ptr<TestWebGraphicsContext3D> context3d) 1167 scoped_ptr<TestWebGraphicsContext3D> context3d)
1144 : FakeOutputSurface( 1168 : FakeOutputSurface(
1145 TestContextProvider::Create(context3d.Pass()), 1169 TestContextProvider::Create(context3d.Pass()),
1146 false) {} 1170 false) {
1147 virtual gfx::Size SurfaceSize() const OVERRIDE { return gfx::Size(500, 500); } 1171 surface_size_ = gfx::Size(500, 500);
1172 }
1173 virtual void Reshape(gfx::Size size, float scale_factor) OVERRIDE {}
1174 void set_fixed_size(gfx::Size size) { surface_size_ = size; }
1148 }; 1175 };
1149 1176
1150 class OffsetViewportRendererClient : public FakeRendererClient { 1177 TEST(GLRendererTest2, NoDiscardOnPartialUpdates) {
1151 public: 1178 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
1152 virtual gfx::Rect DeviceViewport() const OVERRIDE { 1179 DiscardCheckingContext* context = context_owned.get();
1153 return gfx::Rect(10, 10, 100, 100); 1180
1181 FakeOutputSurfaceClient output_surface_client;
1182 scoped_ptr<NonReshapableOutputSurface> output_surface(
1183 new NonReshapableOutputSurface(
1184 context_owned.PassAs<TestWebGraphicsContext3D>()));
1185 CHECK(output_surface->BindToClient(&output_surface_client));
1186 output_surface->set_fixed_size(gfx::Size(100, 100));
1187
1188 scoped_ptr<ResourceProvider> resource_provider(
1189 ResourceProvider::Create(output_surface.get(), 0));
1190
1191 LayerTreeSettings settings;
1192 settings.partial_swap_enabled = true;
1193 FakeRendererClient renderer_client;
1194 renderer_client.set_viewport(gfx::Rect(0, 0, 100, 100));
1195 renderer_client.set_clip(gfx::Rect(0, 0, 100, 100));
1196 FakeRendererGL renderer(&renderer_client,
1197 &settings,
1198 output_surface.get(),
1199 resource_provider.get());
1200 EXPECT_TRUE(renderer.Initialize());
1201 EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
1202
1203 gfx::Rect viewport_rect(renderer_client.DeviceViewport());
1204 ScopedPtrVector<RenderPass>& render_passes =
1205 *renderer_client.render_passes_in_draw_order();
1206 render_passes.clear();
1207
1208 {
1209 // Partial frame, should not discard.
1210 RenderPass::Id root_pass_id(1, 0);
1211 TestRenderPass* root_pass = AddRenderPass(
1212 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1213 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1214 root_pass->damage_rect = gfx::RectF(2.f, 2.f, 3.f, 3.f);
1215
1216 renderer.DecideRenderPassAllocationsForFrame(
1217 *renderer_client.render_passes_in_draw_order());
1218 renderer.DrawFrame(
1219 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1220 EXPECT_EQ(0, context->discarded());
1221 context->reset();
1154 } 1222 }
1155 }; 1223 {
1224 // Full frame, should discard.
1225 RenderPass::Id root_pass_id(1, 0);
1226 TestRenderPass* root_pass = AddRenderPass(
1227 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1228 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1229 root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
1230
1231 renderer.DecideRenderPassAllocationsForFrame(
1232 *renderer_client.render_passes_in_draw_order());
1233 renderer.DrawFrame(
1234 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1235 EXPECT_EQ(1, context->discarded());
1236 context->reset();
1237 }
1238 {
1239 // Partial frame, disallow partial swap, should discard.
1240 RenderPass::Id root_pass_id(1, 0);
1241 TestRenderPass* root_pass = AddRenderPass(
1242 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1243 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1244 root_pass->damage_rect = gfx::RectF(2.f, 2.f, 3.f, 3.f);
1245
1246 renderer.DecideRenderPassAllocationsForFrame(
1247 *renderer_client.render_passes_in_draw_order());
1248 renderer.DrawFrame(
1249 renderer_client.render_passes_in_draw_order(), NULL, 1.f, false);
1250 EXPECT_EQ(1, context->discarded());
1251 context->reset();
1252 }
1253 {
1254 // Full frame, external scissor is set, should not discard.
1255 output_surface->set_has_external_stencil_test(true);
1256 RenderPass::Id root_pass_id(1, 0);
1257 TestRenderPass* root_pass = AddRenderPass(
1258 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1259 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1260 root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
1261
1262 renderer.DecideRenderPassAllocationsForFrame(
1263 *renderer_client.render_passes_in_draw_order());
1264 renderer.DrawFrame(
1265 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1266 EXPECT_EQ(0, context->discarded());
1267 context->reset();
1268 output_surface->set_has_external_stencil_test(false);
1269 }
1270 {
1271 // Full frame, clipped, should not discard.
1272 renderer_client.set_clip(gfx::Rect(10, 10, 10, 10));
1273 RenderPass::Id root_pass_id(1, 0);
1274 TestRenderPass* root_pass = AddRenderPass(
1275 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1276 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1277 root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
1278
1279 renderer.DecideRenderPassAllocationsForFrame(
1280 *renderer_client.render_passes_in_draw_order());
1281 renderer.DrawFrame(
1282 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1283 EXPECT_EQ(0, context->discarded());
1284 context->reset();
1285 }
1286 {
1287 // Full frame, doesn't cover the surface, should not discard.
1288 renderer_client.set_viewport(gfx::Rect(10, 10, 10, 10));
1289 viewport_rect = renderer_client.DeviceViewport();
1290 RenderPass::Id root_pass_id(1, 0);
1291 TestRenderPass* root_pass = AddRenderPass(
1292 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1293 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1294 root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
1295
1296 renderer.DecideRenderPassAllocationsForFrame(
1297 *renderer_client.render_passes_in_draw_order());
1298 renderer.DrawFrame(
1299 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1300 EXPECT_EQ(0, context->discarded());
1301 context->reset();
1302 }
1303 {
1304 // Full frame, doesn't cover the surface (no offset), should not discard.
1305 renderer_client.set_viewport(gfx::Rect(0, 0, 50, 50));
1306 renderer_client.set_clip(gfx::Rect(0, 0, 100, 100));
1307 viewport_rect = renderer_client.DeviceViewport();
1308 RenderPass::Id root_pass_id(1, 0);
1309 TestRenderPass* root_pass = AddRenderPass(
1310 &render_passes, root_pass_id, viewport_rect, gfx::Transform());
1311 AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
1312 root_pass->damage_rect = gfx::RectF(root_pass->output_rect);
1313
1314 renderer.DecideRenderPassAllocationsForFrame(
1315 *renderer_client.render_passes_in_draw_order());
1316 renderer.DrawFrame(
1317 renderer_client.render_passes_in_draw_order(), NULL, 1.f, true);
1318 EXPECT_EQ(0, context->discarded());
1319 context->reset();
1320 }
1321 }
1156 1322
1157 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D { 1323 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
1158 public: 1324 public:
1159 FlippedScissorAndViewportContext() 1325 FlippedScissorAndViewportContext()
1160 : did_call_viewport_(false), did_call_scissor_(false) {} 1326 : did_call_viewport_(false), did_call_scissor_(false) {}
1161 virtual ~FlippedScissorAndViewportContext() { 1327 virtual ~FlippedScissorAndViewportContext() {
1162 EXPECT_TRUE(did_call_viewport_); 1328 EXPECT_TRUE(did_call_viewport_);
1163 EXPECT_TRUE(did_call_scissor_); 1329 EXPECT_TRUE(did_call_scissor_);
1164 } 1330 }
1165 1331
(...skipping 28 matching lines...) Expand all
1194 1360
1195 FakeOutputSurfaceClient output_surface_client; 1361 FakeOutputSurfaceClient output_surface_client;
1196 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface( 1362 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface(
1197 context_owned.PassAs<TestWebGraphicsContext3D>())); 1363 context_owned.PassAs<TestWebGraphicsContext3D>()));
1198 CHECK(output_surface->BindToClient(&output_surface_client)); 1364 CHECK(output_surface->BindToClient(&output_surface_client));
1199 1365
1200 scoped_ptr<ResourceProvider> resource_provider( 1366 scoped_ptr<ResourceProvider> resource_provider(
1201 ResourceProvider::Create(output_surface.get(), 0, false)); 1367 ResourceProvider::Create(output_surface.get(), 0, false));
1202 1368
1203 LayerTreeSettings settings; 1369 LayerTreeSettings settings;
1204 OffsetViewportRendererClient renderer_client; 1370 FakeRendererClient renderer_client;
1371 renderer_client.set_viewport(gfx::Rect(10, 10, 100, 100));
1372 renderer_client.set_clip(gfx::Rect(10, 10, 100, 100));
1205 FakeRendererGL renderer(&renderer_client, 1373 FakeRendererGL renderer(&renderer_client,
1206 &settings, 1374 &settings,
1207 output_surface.get(), 1375 output_surface.get(),
1208 resource_provider.get()); 1376 resource_provider.get());
1209 EXPECT_TRUE(renderer.Initialize()); 1377 EXPECT_TRUE(renderer.Initialize());
1210 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); 1378 EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
1211 1379
1212 gfx::Rect viewport_rect(renderer_client.DeviceViewport().size()); 1380 gfx::Rect viewport_rect(renderer_client.DeviceViewport().size());
1213 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20); 1381 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
1214 ScopedPtrVector<RenderPass>& render_passes = 1382 ScopedPtrVector<RenderPass>& render_passes =
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1599 1767
1600 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1768 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1601 renderer_->SwapBuffers(); 1769 renderer_->SwapBuffers();
1602 } 1770 }
1603 1771
1604 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) { 1772 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
1605 DrawFrame(1.f); 1773 DrawFrame(1.f);
1606 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1774 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1607 renderer_->SwapBuffers(); 1775 renderer_->SwapBuffers();
1608 1776
1609 set_viewport(gfx::Size(2, 2)); 1777 set_viewport(gfx::Rect(0, 0, 2, 2));
1610 renderer_->ViewportChanged(); 1778 renderer_->ViewportChanged();
1611 1779
1612 DrawFrame(2.f); 1780 DrawFrame(2.f);
1613 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1781 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1614 renderer_->SwapBuffers(); 1782 renderer_->SwapBuffers();
1615 1783
1616 DrawFrame(2.f); 1784 DrawFrame(2.f);
1617 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1785 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1618 renderer_->SwapBuffers(); 1786 renderer_->SwapBuffers();
1619 1787
1620 set_viewport(gfx::Size(1, 1)); 1788 set_viewport(gfx::Rect(0, 0, 1, 1));
1621 renderer_->ViewportChanged(); 1789 renderer_->ViewportChanged();
1622 1790
1623 DrawFrame(1.f); 1791 DrawFrame(1.f);
1624 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1792 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
1625 renderer_->SwapBuffers(); 1793 renderer_->SwapBuffers();
1626 } 1794 }
1627 1795
1628 class GLRendererTestSyncPoint : public GLRendererPixelTest { 1796 class GLRendererTestSyncPoint : public GLRendererPixelTest {
1629 protected: 1797 protected:
1630 static void SyncPointCallback(int* callback_count) { 1798 static void SyncPointCallback(int* callback_count) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 base::MessageLoop::current()->Run(); 1860 base::MessageLoop::current()->Run();
1693 1861
1694 // The sync point should have happened. 1862 // The sync point should have happened.
1695 EXPECT_EQ(1, sync_point_callback_count); 1863 EXPECT_EQ(1, sync_point_callback_count);
1696 EXPECT_EQ(1, other_callback_count); 1864 EXPECT_EQ(1, other_callback_count);
1697 } 1865 }
1698 #endif // OS_ANDROID 1866 #endif // OS_ANDROID
1699 1867
1700 } // namespace 1868 } // namespace
1701 } // namespace cc 1869 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698