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

Unified Diff: cc/output/output_surface_unittest.cc

Issue 16833003: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/output_surface_client.h ('k') | cc/scheduler/frame_rate_controller.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/output_surface_unittest.cc
diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc
index ebc018f8ea61a0b2ea37ac26c1adffd8b8673b01..7dcb1cce0fe59ea65f5f6cc51634e3c0a85a9cf5 100644
--- a/cc/output/output_surface_unittest.cc
+++ b/cc/output/output_surface_unittest.cc
@@ -5,6 +5,7 @@
#include "cc/output/output_surface.h"
#include "cc/output/output_surface_client.h"
#include "cc/output/software_output_device.h"
+#include "cc/test/scheduler_test_common.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "gpu/GLES2/gl2extchromium.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -25,19 +26,43 @@ class TestOutputSurface : public OutputSurface {
scoped_ptr<cc::SoftwareOutputDevice> software_device)
: OutputSurface(context3d.Pass(), software_device.Pass()) {}
- OutputSurfaceClient* client() { return client_; }
-
bool InitializeNewContext3D(
scoped_ptr<WebKit::WebGraphicsContext3D> new_context3d) {
return InitializeAndSetContext3D(new_context3d.Pass(),
scoped_refptr<ContextProvider>());
}
+
+ bool HasClientForTesting() {
+ return HasClient();
+ }
+
+ void OnVSyncParametersChangedForTesting(base::TimeTicks timebase,
+ base::TimeDelta interval) {
+ OnVSyncParametersChanged(timebase, interval);
+ }
+
+ void BeginFrameForTesting(base::TimeTicks frame_time) {
+ BeginFrame(frame_time);
+ }
+
+ void DidSwapBuffersForTesting() {
+ DidSwapBuffers();
+ }
+
+ int pending_swap_buffers() {
+ return pending_swap_buffers_;
+ }
+
+ void OnSwapBuffersCompleteForTesting() {
+ OnSwapBuffersComplete(NULL);
+ }
};
class FakeOutputSurfaceClient : public OutputSurfaceClient {
public:
FakeOutputSurfaceClient()
- : deferred_initialize_result_(true),
+ : begin_frame_count_(0),
+ deferred_initialize_result_(true),
deferred_initialize_called_(false),
did_lose_output_surface_called_(false) {}
@@ -47,9 +72,9 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
return deferred_initialize_result_;
}
virtual void SetNeedsRedrawRect(gfx::Rect damage_rect) OVERRIDE {}
- virtual void OnVSyncParametersChanged(base::TimeTicks timebase,
- base::TimeDelta interval) OVERRIDE {}
- virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE {}
+ virtual void BeginFrame(base::TimeTicks frame_time) OVERRIDE {
+ begin_frame_count_++;
+ }
virtual void OnSwapBuffersComplete(const CompositorFrameAck* ack) OVERRIDE {}
virtual void DidLoseOutputSurface() OVERRIDE {
did_lose_output_surface_called_ = true;
@@ -57,6 +82,10 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
virtual void SetExternalDrawConstraints(const gfx::Transform& transform,
gfx::Rect viewport) OVERRIDE {}
+ int begin_frame_count() {
+ return begin_frame_count_;
+ }
+
void set_deferred_initialize_result(bool result) {
deferred_initialize_result_ = result;
}
@@ -70,6 +99,7 @@ class FakeOutputSurfaceClient : public OutputSurfaceClient {
}
private:
+ int begin_frame_count_;
bool deferred_initialize_result_;
bool deferred_initialize_called_;
bool did_lose_output_surface_called_;
@@ -81,11 +111,11 @@ TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) {
TestOutputSurface output_surface(
context3d.PassAs<WebKit::WebGraphicsContext3D>());
- EXPECT_EQ(NULL, output_surface.client());
+ EXPECT_FALSE(output_surface.HasClientForTesting());
FakeOutputSurfaceClient client;
EXPECT_TRUE(output_surface.BindToClient(&client));
- EXPECT_EQ(&client, output_surface.client());
+ EXPECT_TRUE(output_surface.HasClientForTesting());
EXPECT_FALSE(client.deferred_initialize_called());
// Verify DidLoseOutputSurface callback is hooked up correctly.
@@ -104,11 +134,11 @@ TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientFailure) {
TestOutputSurface output_surface(
context3d.PassAs<WebKit::WebGraphicsContext3D>());
- EXPECT_EQ(NULL, output_surface.client());
+ EXPECT_FALSE(output_surface.HasClientForTesting());
FakeOutputSurfaceClient client;
EXPECT_FALSE(output_surface.BindToClient(&client));
- EXPECT_EQ(NULL, output_surface.client());
+ EXPECT_FALSE(output_surface.HasClientForTesting());
}
class InitializeNewContext3D : public ::testing::Test {
@@ -121,13 +151,13 @@ class InitializeNewContext3D : public ::testing::Test {
protected:
void BindOutputSurface() {
EXPECT_TRUE(output_surface_.BindToClient(&client_));
- EXPECT_EQ(&client_, output_surface_.client());
+ EXPECT_TRUE(output_surface_.HasClientForTesting());
}
void InitializeNewContextExpectFail() {
EXPECT_FALSE(output_surface_.InitializeNewContext3D(
context3d_.PassAs<WebKit::WebGraphicsContext3D>()));
- EXPECT_EQ(&client_, output_surface_.client());
+ EXPECT_TRUE(output_surface_.HasClientForTesting());
EXPECT_FALSE(output_surface_.context3d());
EXPECT_TRUE(output_surface_.software_device());
@@ -164,5 +194,110 @@ TEST_F(InitializeNewContext3D, ClientDeferredInitializeFails) {
InitializeNewContextExpectFail();
}
+TEST(OutputSurfaceTest, BeginFrameEmulation) {
+ scoped_ptr<TestWebGraphicsContext3D> context3d =
+ TestWebGraphicsContext3D::Create();
+
+ TestOutputSurface output_surface(
+ context3d.PassAs<WebKit::WebGraphicsContext3D>());
+ EXPECT_FALSE(output_surface.HasClientForTesting());
+
+ FakeOutputSurfaceClient client;
+ EXPECT_TRUE(output_surface.BindToClient(&client));
+ EXPECT_TRUE(output_surface.HasClientForTesting());
+ EXPECT_FALSE(client.deferred_initialize_called());
+
+ // Initialize BeginFrame emulation
+ FakeThread impl_thread;
+ bool throttle_frame_production = true;
+ const base::TimeDelta display_refresh_interval =
+ base::TimeDelta::FromMicroseconds(16666);
+
+ output_surface.InitializeBeginFrameEmulation(
+ &impl_thread,
+ throttle_frame_production,
+ display_refresh_interval);
+
+ output_surface.SetMaxFramesPending(2);
+
+ // We should start off with 0 BeginFrames
+ EXPECT_EQ(client.begin_frame_count(), 0);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
+
+ // We should not have a pending task until a BeginFrame has been requested.
+ EXPECT_FALSE(impl_thread.HasPendingTask());
+ output_surface.SetNeedsBeginFrame(true);
+ EXPECT_TRUE(impl_thread.HasPendingTask());
+
+ // BeginFrame should be called on the first tick.
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
+
+ // BeginFrame should not be called when there is a pending BeginFrame.
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 0);
+
+ // DidSwapBuffers should clear the pending BeginFrame.
+ output_surface.DidSwapBuffersForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 1);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // BeginFrame should be throttled by pending swap buffers.
+ output_surface.DidSwapBuffersForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
+
+ // SwapAck should decrement pending swap buffers and unblock BeginFrame again.
+ output_surface.OnSwapBuffersCompleteForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 2);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 3);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // Calling SetNeedsBeginFrame again indicates a swap did not occur but
+ // the client still wants another BeginFrame.
+ output_surface.SetNeedsBeginFrame(true);
+ impl_thread.RunPendingTask();
+ EXPECT_EQ(client.begin_frame_count(), 4);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // Disabling SetNeedsBeginFrame should prevent further BeginFrames.
+ output_surface.SetNeedsBeginFrame(false);
+ impl_thread.RunPendingTask();
+ EXPECT_FALSE(impl_thread.HasPendingTask());
+ EXPECT_EQ(client.begin_frame_count(), 4);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // Optimistically injected BeginFrames without a SetNeedsBeginFrame should be
+ // allowed.
+ output_surface.BeginFrameForTesting(base::TimeTicks::Now());
+ EXPECT_EQ(client.begin_frame_count(), 5);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // Optimistically injected BeginFrames without a SetNeedsBeginFrame should
+ // still be throttled by pending begin frames however.
+ output_surface.BeginFrameForTesting(base::TimeTicks::Now());
+ EXPECT_EQ(client.begin_frame_count(), 5);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 1);
+
+ // Optimistically injected BeginFrames without a SetNeedsBeginFrame should
+ // also be throttled by pending swap buffers.
+ output_surface.DidSwapBuffersForTesting();
+ EXPECT_EQ(client.begin_frame_count(), 5);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
+ output_surface.BeginFrameForTesting(base::TimeTicks::Now());
+ EXPECT_EQ(client.begin_frame_count(), 5);
+ EXPECT_EQ(output_surface.pending_swap_buffers(), 2);
+}
+
} // namespace
} // namespace cc
« no previous file with comments | « cc/output/output_surface_client.h ('k') | cc/scheduler/frame_rate_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698