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

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

Issue 15836005: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@nofrc
Patch Set: Fix checkerboard; Track pending swaps; 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/output_surface.h" 5 #include "cc/output/output_surface.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/debug/trace_event.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/string_util.h" 13 #include "base/string_util.h"
13 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
14 #include "cc/output/output_surface_client.h" 15 #include "cc/output/output_surface_client.h"
16 #include "cc/scheduler/delay_based_time_source.h"
15 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 17 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
16 #include "third_party/khronos/GLES2/gl2.h" 18 #include "third_party/khronos/GLES2/gl2.h"
17 #include "third_party/khronos/GLES2/gl2ext.h" 19 #include "third_party/khronos/GLES2/gl2ext.h"
18 #include "ui/gfx/rect.h" 20 #include "ui/gfx/rect.h"
19 #include "ui/gfx/size.h" 21 #include "ui/gfx/size.h"
20 22
21 using std::set; 23 using std::set;
22 using std::string; 24 using std::string;
23 using std::vector; 25 using std::vector;
24 26
25 namespace cc { 27 namespace cc {
26 28
27 class OutputSurfaceCallbacks 29 class OutputSurfaceCallbacks
28 : public WebKit::WebGraphicsContext3D:: 30 : public WebKit::WebGraphicsContext3D::
29 WebGraphicsSwapBuffersCompleteCallbackCHROMIUM, 31 WebGraphicsSwapBuffersCompleteCallbackCHROMIUM,
30 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { 32 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
31 public: 33 public:
32 explicit OutputSurfaceCallbacks(OutputSurfaceClient* client) 34 explicit OutputSurfaceCallbacks(OutputSurface* client)
33 : client_(client) {} 35 : client_(client) {}
34 36
35 // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation. 37 // WK:WGC3D::WGSwapBuffersCompleteCallbackCHROMIUM implementation.
36 virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(); } 38 virtual void onSwapBuffersComplete() { client_->OnSwapBuffersComplete(); }
37 39
38 // WK:WGC3D::WGContextLostCallback implementation. 40 // WK:WGC3D::WGContextLostCallback implementation.
39 virtual void onContextLost() { client_->DidLoseOutputSurface(); } 41 virtual void onContextLost() { client_->DidLoseOutputSurface(); }
40 42
41 private: 43 private:
42 OutputSurfaceClient* client_; 44 OutputSurface* client_;
43 }; 45 };
44 46
45 OutputSurface::OutputSurface( 47 OutputSurface::OutputSurface(
46 scoped_ptr<WebKit::WebGraphicsContext3D> context3d) 48 scoped_ptr<WebKit::WebGraphicsContext3D> context3d)
47 : client_(NULL), 49 : client_(NULL),
48 context3d_(context3d.Pass()), 50 context3d_(context3d.Pass()),
49 has_gl_discard_backbuffer_(false) { 51 has_gl_discard_backbuffer_(false),
52 pending_begin_frames_(0),
53 pending_swap_buffers_(0) {
50 } 54 }
51 55
52 OutputSurface::OutputSurface( 56 OutputSurface::OutputSurface(
53 scoped_ptr<cc::SoftwareOutputDevice> software_device) 57 scoped_ptr<cc::SoftwareOutputDevice> software_device)
54 : client_(NULL), 58 : client_(NULL),
55 software_device_(software_device.Pass()), 59 software_device_(software_device.Pass()),
56 has_gl_discard_backbuffer_(false) { 60 has_gl_discard_backbuffer_(false),
61 pending_begin_frames_(0),
62 pending_swap_buffers_(0) {
57 } 63 }
58 64
59 OutputSurface::OutputSurface( 65 OutputSurface::OutputSurface(
60 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 66 scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
61 scoped_ptr<cc::SoftwareOutputDevice> software_device) 67 scoped_ptr<cc::SoftwareOutputDevice> software_device)
62 : client_(NULL), 68 : client_(NULL),
63 context3d_(context3d.Pass()), 69 context3d_(context3d.Pass()),
64 software_device_(software_device.Pass()), 70 software_device_(software_device.Pass()),
65 has_gl_discard_backbuffer_(false) { 71 has_gl_discard_backbuffer_(false),
72 pending_begin_frames_(0),
73 pending_swap_buffers_(0) {
74 }
75
76 void OutputSurface::InitializeBeginFrameEmulation(
77 Thread* thread,
78 bool throttle_frame_production,
79 base::TimeDelta interval,
80 int max_frames_pending,
81 bool swap_buffers_complete_supported) {
82 DCHECK(!frame_rate_controller_);
83 if (throttle_frame_production){
84 frame_rate_controller_.reset(
85 new FrameRateController(
86 DelayBasedTimeSource::Create(interval, thread)));
87 } else {
88 frame_rate_controller_.reset(new FrameRateController(thread));
89 }
90
91 frame_rate_controller_->SetClient(this);
92 frame_rate_controller_->SetSwapBuffersCompleteSupported(
93 swap_buffers_complete_supported);
94 frame_rate_controller_->SetMaxFramesPending(max_frames_pending);
95 }
96
97 void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase,
98 base::TimeDelta interval) {
99 TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged",
100 "timebase", (timebase - base::TimeTicks()).InSecondsF(),
101 "interval", interval.InSecondsF());
102 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
103 }
104
105 void OutputSurface::FrameRateControllerTick(bool throttled) {
106 if (!throttled)
107 BeginFrame(frame_rate_controller_->LastTickTime());
108 }
109
110 // Forwarded to OutputSurfaceClient
111 void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
112 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
113 client_->SetNeedsRedrawRect(damage_rect);
114 }
115
116 void OutputSurface::SetNeedsBeginFrame(bool enable) {
117 frame_rate_controller_->SetActive(enable);
118 }
119
120 void OutputSurface::BeginFrame(base::TimeTicks frame_time) {
121 // TODO(brianderson): Remove this early return once Android has
122 // Browser-side throttling.
123 if (pending_begin_frames_ ||
124 pending_swap_buffers_ >= frame_rate_controller_->MaxFramesPending())
125 return;
126 TRACE_EVENT0("cc", "OutputSurface::BeginFrame");
127 pending_begin_frames_++;
128 frame_rate_controller_->WillSwapBuffers();
129 client_->BeginFrame(frame_time);
130 }
131
132 void OutputSurface::OnSendFrameToParentCompositorAck(
133 const CompositorFrameAck& ack) {
134 TRACE_EVENT0("cc", "OutputSurface::OnSendFrameToParentCompositorAck");
135 client_->OnSendFrameToParentCompositorAck(ack);
136 }
137
138 void OutputSurface::DidSwapBuffers() {
139 pending_begin_frames_--;
140 pending_swap_buffers_++;
141 }
142
143 void OutputSurface::OnSwapBuffersComplete() {
144 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
145 pending_swap_buffers_--;
146 client_->OnSwapBuffersComplete();
147 frame_rate_controller_->DidSwapBuffersComplete();
148 }
149
150 void OutputSurface::DidLoseOutputSurface() {
151 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
152 pending_begin_frames_ = 0;
153 pending_swap_buffers_ = 0;
154 client_->DidLoseOutputSurface();
66 } 155 }
67 156
68 OutputSurface::~OutputSurface() { 157 OutputSurface::~OutputSurface() {
158 if (frame_rate_controller_)
159 frame_rate_controller_->SetActive(false);
69 } 160 }
70 161
71 bool OutputSurface::ForcedDrawToSoftwareDevice() const { 162 bool OutputSurface::ForcedDrawToSoftwareDevice() const {
72 return false; 163 return false;
73 } 164 }
74 165
75 bool OutputSurface::BindToClient( 166 bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
76 cc::OutputSurfaceClient* client) {
77 DCHECK(client); 167 DCHECK(client);
78 if (context3d_ && !context3d_->makeContextCurrent()) 168 if (context3d_ && !context3d_->makeContextCurrent())
79 return false; 169 return false;
80 client_ = client; 170 client_ = client;
81 if (!context3d_) 171 if (!context3d_)
82 return true; 172 return true;
83 string extensions_string = UTF16ToASCII(context3d_->getString(GL_EXTENSIONS)); 173 string extensions_string = UTF16ToASCII(context3d_->getString(GL_EXTENSIONS));
84 vector<string> extensions_list; 174 vector<string> extensions_list;
85 base::SplitString(extensions_string, ' ', &extensions_list); 175 base::SplitString(extensions_string, ' ', &extensions_list);
86 set<string> extensions(extensions_list.begin(), extensions_list.end()); 176 set<string> extensions(extensions_list.begin(), extensions_list.end());
87 177
88 has_gl_discard_backbuffer_ = 178 has_gl_discard_backbuffer_ =
89 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; 179 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0;
90 180
91 callbacks_.reset(new OutputSurfaceCallbacks(client_)); 181 callbacks_.reset(new OutputSurfaceCallbacks(this));
92 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); 182 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
93 context3d_->setContextLostCallback(callbacks_.get()); 183 context3d_->setContextLostCallback(callbacks_.get());
94 184
95 return true; 185 return true;
96 } 186 }
97 187
98 void OutputSurface::SendFrameToParentCompositor(CompositorFrame* frame) { 188 void OutputSurface::SendFrameToParentCompositor(CompositorFrame* frame) {
99 NOTIMPLEMENTED(); 189 NOTIMPLEMENTED();
100 } 190 }
101 191
(...skipping 17 matching lines...) Expand all
119 void OutputSurface::BindFramebuffer() { 209 void OutputSurface::BindFramebuffer() {
120 DCHECK(context3d_); 210 DCHECK(context3d_);
121 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0); 211 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0);
122 } 212 }
123 213
124 void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) { 214 void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) {
125 DCHECK(context3d_); 215 DCHECK(context3d_);
126 // Note that currently this has the same effect as SwapBuffers; we should 216 // Note that currently this has the same effect as SwapBuffers; we should
127 // consider exposing a different entry point on WebGraphicsContext3D. 217 // consider exposing a different entry point on WebGraphicsContext3D.
128 context3d_->prepareTexture(); 218 context3d_->prepareTexture();
219 DidSwapBuffers();
129 } 220 }
130 221
131 void OutputSurface::PostSubBuffer(gfx::Rect rect, 222 void OutputSurface::PostSubBuffer(gfx::Rect rect,
132 const ui::LatencyInfo& latency_info) { 223 const ui::LatencyInfo& latency_info) {
133 DCHECK(context3d_); 224 DCHECK(context3d_);
134 context3d_->postSubBufferCHROMIUM( 225 context3d_->postSubBufferCHROMIUM(
135 rect.x(), rect.y(), rect.width(), rect.height()); 226 rect.x(), rect.y(), rect.width(), rect.height());
227 DidSwapBuffers();
136 } 228 }
137 229
138 } // namespace cc 230 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698