Task Manager: Remove goat teleporter.
[chromium-blink-merge.git] / cc / output / output_surface.cc
bloba0efb6fdb28addad45dc62f4ee3c097320a334ad
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
3 // found in the LICENSE file.
5 #include "cc/output/output_surface.h"
7 #include <algorithm>
8 #include <set>
9 #include <string>
10 #include <vector>
12 #include "base/bind.h"
13 #include "base/debug/trace_event.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/strings/string_split.h"
18 #include "base/strings/string_util.h"
19 #include "cc/output/compositor_frame.h"
20 #include "cc/output/compositor_frame_ack.h"
21 #include "cc/output/managed_memory_policy.h"
22 #include "cc/output/output_surface_client.h"
23 #include "cc/scheduler/delay_based_time_source.h"
24 #include "gpu/command_buffer/client/context_support.h"
25 #include "gpu/command_buffer/client/gles2_interface.h"
26 #include "ui/gfx/frame_time.h"
27 #include "ui/gfx/geometry/rect.h"
28 #include "ui/gfx/geometry/size.h"
30 using std::set;
31 using std::string;
32 using std::vector;
34 namespace cc {
36 OutputSurface::OutputSurface(
37 const scoped_refptr<ContextProvider>& context_provider)
38 : client_(NULL),
39 context_provider_(context_provider),
40 device_scale_factor_(-1),
41 external_stencil_test_enabled_(false),
42 weak_ptr_factory_(this) {
45 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
46 : client_(NULL),
47 software_device_(software_device.Pass()),
48 device_scale_factor_(-1),
49 external_stencil_test_enabled_(false),
50 weak_ptr_factory_(this) {
53 OutputSurface::OutputSurface(
54 const scoped_refptr<ContextProvider>& context_provider,
55 scoped_ptr<SoftwareOutputDevice> software_device)
56 : client_(NULL),
57 context_provider_(context_provider),
58 software_device_(software_device.Pass()),
59 device_scale_factor_(-1),
60 external_stencil_test_enabled_(false),
61 weak_ptr_factory_(this) {
64 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
65 base::TimeDelta interval) {
66 TRACE_EVENT2("cc",
67 "OutputSurface::CommitVSyncParameters",
68 "timebase",
69 (timebase - base::TimeTicks()).InSecondsF(),
70 "interval",
71 interval.InSecondsF());
72 client_->CommitVSyncParameters(timebase, interval);
75 // Forwarded to OutputSurfaceClient
76 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
77 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
78 client_->SetNeedsRedrawRect(damage_rect);
81 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
82 client_->ReclaimResources(ack);
85 void OutputSurface::DidLoseOutputSurface() {
86 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
87 client_->DidLoseOutputSurface();
90 void OutputSurface::SetExternalStencilTest(bool enabled) {
91 external_stencil_test_enabled_ = enabled;
94 void OutputSurface::SetExternalDrawConstraints(
95 const gfx::Transform& transform,
96 const gfx::Rect& viewport,
97 const gfx::Rect& clip,
98 const gfx::Rect& viewport_rect_for_tile_priority,
99 const gfx::Transform& transform_for_tile_priority,
100 bool resourceless_software_draw) {
101 client_->SetExternalDrawConstraints(transform,
102 viewport,
103 clip,
104 viewport_rect_for_tile_priority,
105 transform_for_tile_priority,
106 resourceless_software_draw);
109 OutputSurface::~OutputSurface() {
110 ResetContext3d();
113 bool OutputSurface::HasExternalStencilTest() const {
114 return external_stencil_test_enabled_;
117 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
118 DCHECK(client);
119 client_ = client;
120 bool success = true;
122 if (context_provider_.get()) {
123 success = context_provider_->BindToCurrentThread();
124 if (success)
125 SetUpContext3d();
128 if (!success)
129 client_ = NULL;
131 return success;
134 bool OutputSurface::InitializeAndSetContext3d(
135 scoped_refptr<ContextProvider> context_provider) {
136 DCHECK(!context_provider_.get());
137 DCHECK(context_provider.get());
138 DCHECK(client_);
140 bool success = false;
141 if (context_provider->BindToCurrentThread()) {
142 context_provider_ = context_provider;
143 SetUpContext3d();
144 client_->DeferredInitialize();
145 success = true;
148 if (!success)
149 ResetContext3d();
151 return success;
154 void OutputSurface::ReleaseGL() {
155 DCHECK(client_);
156 DCHECK(context_provider_.get());
157 client_->ReleaseGL();
158 DCHECK(!context_provider_.get());
161 void OutputSurface::SetUpContext3d() {
162 DCHECK(context_provider_.get());
163 DCHECK(client_);
165 context_provider_->SetLostContextCallback(
166 base::Bind(&OutputSurface::DidLoseOutputSurface,
167 base::Unretained(this)));
168 context_provider_->ContextSupport()->SetSwapBuffersCompleteCallback(
169 base::Bind(&OutputSurface::OnSwapBuffersComplete,
170 base::Unretained(this)));
171 context_provider_->SetMemoryPolicyChangedCallback(
172 base::Bind(&OutputSurface::SetMemoryPolicy,
173 base::Unretained(this)));
176 void OutputSurface::ReleaseContextProvider() {
177 DCHECK(client_);
178 DCHECK(context_provider_.get());
179 ResetContext3d();
182 void OutputSurface::ResetContext3d() {
183 if (context_provider_.get()) {
184 context_provider_->SetLostContextCallback(
185 ContextProvider::LostContextCallback());
186 context_provider_->SetMemoryPolicyChangedCallback(
187 ContextProvider::MemoryPolicyChangedCallback());
188 if (gpu::ContextSupport* support = context_provider_->ContextSupport())
189 support->SetSwapBuffersCompleteCallback(base::Closure());
191 context_provider_ = NULL;
194 void OutputSurface::EnsureBackbuffer() {
195 if (software_device_)
196 software_device_->EnsureBackbuffer();
199 void OutputSurface::DiscardBackbuffer() {
200 if (context_provider_.get())
201 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
202 if (software_device_)
203 software_device_->DiscardBackbuffer();
206 void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
207 if (size == surface_size_ && scale_factor == device_scale_factor_)
208 return;
210 surface_size_ = size;
211 device_scale_factor_ = scale_factor;
212 if (context_provider_.get()) {
213 context_provider_->ContextGL()->ResizeCHROMIUM(
214 size.width(), size.height(), scale_factor);
216 if (software_device_)
217 software_device_->Resize(size, scale_factor);
220 gfx::Size OutputSurface::SurfaceSize() const {
221 return surface_size_;
224 void OutputSurface::BindFramebuffer() {
225 DCHECK(context_provider_.get());
226 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
229 void OutputSurface::SwapBuffers(CompositorFrame* frame) {
230 if (frame->software_frame_data) {
231 PostSwapBuffersComplete();
232 client_->DidSwapBuffers();
233 return;
236 DCHECK(context_provider_.get());
237 DCHECK(frame->gl_frame_data);
239 if (frame->gl_frame_data->sub_buffer_rect ==
240 gfx::Rect(frame->gl_frame_data->size)) {
241 context_provider_->ContextSupport()->Swap();
242 } else {
243 context_provider_->ContextSupport()->PartialSwapBuffers(
244 frame->gl_frame_data->sub_buffer_rect);
247 client_->DidSwapBuffers();
250 void OutputSurface::PostSwapBuffersComplete() {
251 base::MessageLoop::current()->PostTask(
252 FROM_HERE,
253 base::Bind(&OutputSurface::OnSwapBuffersComplete,
254 weak_ptr_factory_.GetWeakPtr()));
257 // We don't post tasks bound to the client directly since they might run
258 // after the OutputSurface has been destroyed.
259 void OutputSurface::OnSwapBuffersComplete() {
260 client_->DidSwapBuffersComplete();
263 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
264 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
265 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
266 // Just ignore the memory manager when it says to set the limit to zero
267 // bytes. This will happen when the memory manager thinks that the renderer
268 // is not visible (which the renderer knows better).
269 if (policy.bytes_limit_when_visible)
270 client_->SetMemoryPolicy(policy);
273 } // namespace cc