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

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: Ignore last patch set: bad upload. 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 max_frames_pending_(0),
53 pending_swap_buffers_(0),
54 begin_frame_pending_(false) {
50 } 55 }
51 56
52 OutputSurface::OutputSurface( 57 OutputSurface::OutputSurface(
53 scoped_ptr<cc::SoftwareOutputDevice> software_device) 58 scoped_ptr<cc::SoftwareOutputDevice> software_device)
54 : client_(NULL), 59 : client_(NULL),
55 software_device_(software_device.Pass()), 60 software_device_(software_device.Pass()),
56 has_gl_discard_backbuffer_(false) { 61 has_gl_discard_backbuffer_(false),
62 max_frames_pending_(0),
63 pending_swap_buffers_(0),
64 begin_frame_pending_(false) {
57 } 65 }
58 66
59 OutputSurface::OutputSurface( 67 OutputSurface::OutputSurface(
60 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 68 scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
61 scoped_ptr<cc::SoftwareOutputDevice> software_device) 69 scoped_ptr<cc::SoftwareOutputDevice> software_device)
62 : client_(NULL), 70 : client_(NULL),
63 context3d_(context3d.Pass()), 71 context3d_(context3d.Pass()),
64 software_device_(software_device.Pass()), 72 software_device_(software_device.Pass()),
65 has_gl_discard_backbuffer_(false) { 73 has_gl_discard_backbuffer_(false),
74 max_frames_pending_(0),
75 pending_swap_buffers_(0),
76 begin_frame_pending_(false) {
77 }
78
79 void OutputSurface::InitializeBeginFrameEmulation(
80 Thread* thread,
81 bool throttle_frame_production,
82 base::TimeDelta interval,
83 bool swap_buffers_complete_supported) {
84 DCHECK(!frame_rate_controller_);
85 if (throttle_frame_production){
86 frame_rate_controller_.reset(
87 new FrameRateController(
88 DelayBasedTimeSource::Create(interval, thread)));
89 } else {
90 frame_rate_controller_.reset(new FrameRateController(thread));
91 }
92
93 frame_rate_controller_->SetClient(this);
94 frame_rate_controller_->SetSwapBuffersCompleteSupported(
95 swap_buffers_complete_supported);
96 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_);
97 }
98
99 void OutputSurface::SetMaxFramesPending(int max_frames_pending) {
100 if (frame_rate_controller_)
101 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending);
102 max_frames_pending_ = max_frames_pending;
103 }
104
105 void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase,
106 base::TimeDelta interval) {
107 TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged",
108 "timebase", (timebase - base::TimeTicks()).InSecondsF(),
109 "interval", interval.InSecondsF());
110 if (frame_rate_controller_)
111 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
112 }
113
114 void OutputSurface::FrameRateControllerTick(bool throttled) {
115 DCHECK(frame_rate_controller_);
116 if (!throttled)
117 BeginFrame(frame_rate_controller_->LastTickTime());
118 }
119
120 // Forwarded to OutputSurfaceClient
121 void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
122 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
123 client_->SetNeedsRedrawRect(damage_rect);
124 }
125
126 void OutputSurface::SetNeedsBeginFrame(bool enable) {
127 begin_frame_pending_ = false;
128 if (frame_rate_controller_)
129 frame_rate_controller_->SetActive(enable);
130 }
131
132 void OutputSurface::BeginFrame(base::TimeTicks frame_time) {
133 // TODO(brianderson): Remove this early return once Android has
134 // Browser-side throttling.
135 if (begin_frame_pending_ || pending_swap_buffers_ >= max_frames_pending_)
136 return;
137 TRACE_EVENT0("cc", "OutputSurface::BeginFrame");
138 begin_frame_pending_ = true;
139 client_->BeginFrame(frame_time);
140 }
141
142 void OutputSurface::OnSendFrameToParentCompositorAck(
143 const CompositorFrameAck& ack) {
144 TRACE_EVENT0("cc", "OutputSurface::OnSendFrameToParentCompositorAck");
145 client_->OnSendFrameToParentCompositorAck(ack);
146 }
147
148 void OutputSurface::DidSwapBuffers() {
149 begin_frame_pending_ = false;
150 pending_swap_buffers_++;
151 if (frame_rate_controller_)
152 frame_rate_controller_->DidSwapBuffers();
153 }
154
155 void OutputSurface::OnSwapBuffersComplete() {
156 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
157 pending_swap_buffers_--;
158 client_->OnSwapBuffersComplete();
159 if (frame_rate_controller_)
160 frame_rate_controller_->DidSwapBuffersComplete();
161 }
162
163 void OutputSurface::DidLoseOutputSurface() {
164 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
165 begin_frame_pending_ = false;
166 pending_swap_buffers_ = 0;
167 client_->DidLoseOutputSurface();
168 if (frame_rate_controller_)
169 frame_rate_controller_->DidAbortAllPendingFrames();
66 } 170 }
67 171
68 OutputSurface::~OutputSurface() { 172 OutputSurface::~OutputSurface() {
173 if (frame_rate_controller_)
174 frame_rate_controller_->SetActive(false);
69 } 175 }
70 176
71 bool OutputSurface::ForcedDrawToSoftwareDevice() const { 177 bool OutputSurface::ForcedDrawToSoftwareDevice() const {
72 return false; 178 return false;
73 } 179 }
74 180
75 bool OutputSurface::BindToClient( 181 bool OutputSurface::BindToClient(cc::OutputSurfaceClient* client) {
76 cc::OutputSurfaceClient* client) {
77 DCHECK(client); 182 DCHECK(client);
78 if (context3d_ && !context3d_->makeContextCurrent()) 183 if (context3d_ && !context3d_->makeContextCurrent())
79 return false; 184 return false;
80 client_ = client; 185 client_ = client;
81 if (!context3d_) 186 if (!context3d_)
82 return true; 187 return true;
83 string extensions_string = UTF16ToASCII(context3d_->getString(GL_EXTENSIONS)); 188 string extensions_string = UTF16ToASCII(context3d_->getString(GL_EXTENSIONS));
84 vector<string> extensions_list; 189 vector<string> extensions_list;
85 base::SplitString(extensions_string, ' ', &extensions_list); 190 base::SplitString(extensions_string, ' ', &extensions_list);
86 set<string> extensions(extensions_list.begin(), extensions_list.end()); 191 set<string> extensions(extensions_list.begin(), extensions_list.end());
87 192
88 has_gl_discard_backbuffer_ = 193 has_gl_discard_backbuffer_ =
89 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0; 194 extensions.count("GL_CHROMIUM_discard_backbuffer") > 0;
90 195
91 callbacks_.reset(new OutputSurfaceCallbacks(client_)); 196 callbacks_.reset(new OutputSurfaceCallbacks(this));
92 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get()); 197 context3d_->setSwapBuffersCompleteCallbackCHROMIUM(callbacks_.get());
93 context3d_->setContextLostCallback(callbacks_.get()); 198 context3d_->setContextLostCallback(callbacks_.get());
94 199
95 return true; 200 return true;
96 } 201 }
97 202
98 void OutputSurface::SendFrameToParentCompositor(CompositorFrame* frame) { 203 void OutputSurface::SendFrameToParentCompositor(CompositorFrame* frame) {
99 NOTIMPLEMENTED(); 204 NOTIMPLEMENTED();
100 } 205 }
101 206
(...skipping 17 matching lines...) Expand all
119 void OutputSurface::BindFramebuffer() { 224 void OutputSurface::BindFramebuffer() {
120 DCHECK(context3d_); 225 DCHECK(context3d_);
121 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0); 226 context3d_->bindFramebuffer(GL_FRAMEBUFFER, 0);
122 } 227 }
123 228
124 void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) { 229 void OutputSurface::SwapBuffers(const ui::LatencyInfo& latency_info) {
125 DCHECK(context3d_); 230 DCHECK(context3d_);
126 // Note that currently this has the same effect as SwapBuffers; we should 231 // Note that currently this has the same effect as SwapBuffers; we should
127 // consider exposing a different entry point on WebGraphicsContext3D. 232 // consider exposing a different entry point on WebGraphicsContext3D.
128 context3d_->prepareTexture(); 233 context3d_->prepareTexture();
234 DidSwapBuffers();
129 } 235 }
130 236
131 void OutputSurface::PostSubBuffer(gfx::Rect rect, 237 void OutputSurface::PostSubBuffer(gfx::Rect rect,
132 const ui::LatencyInfo& latency_info) { 238 const ui::LatencyInfo& latency_info) {
133 DCHECK(context3d_); 239 DCHECK(context3d_);
134 context3d_->postSubBufferCHROMIUM( 240 context3d_->postSubBufferCHROMIUM(
135 rect.x(), rect.y(), rect.width(), rect.height()); 241 rect.x(), rect.y(), rect.width(), rect.height());
242 DidSwapBuffers();
136 } 243 }
137 244
138 } // namespace cc 245 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698