Compute if a layer is clipped outside CalcDrawProps
[chromium-blink-merge.git] / cc / output / output_surface.cc
bloba597a87d8456bc65f3ce763d469db9e7e776ed7f
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 "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "base/trace_event/trace_event.h"
12 #include "cc/output/managed_memory_policy.h"
13 #include "cc/output/output_surface_client.h"
14 #include "gpu/GLES2/gl2extchromium.h"
15 #include "gpu/command_buffer/client/context_support.h"
16 #include "gpu/command_buffer/client/gles2_interface.h"
17 #include "third_party/skia/include/gpu/GrContext.h"
18 #include "ui/gfx/geometry/rect.h"
19 #include "ui/gfx/geometry/size.h"
22 namespace cc {
24 OutputSurface::OutputSurface(
25 const scoped_refptr<ContextProvider>& context_provider,
26 const scoped_refptr<ContextProvider>& worker_context_provider,
27 scoped_ptr<SoftwareOutputDevice> software_device)
28 : client_(NULL),
29 context_provider_(context_provider),
30 worker_context_provider_(worker_context_provider),
31 software_device_(software_device.Pass()),
32 device_scale_factor_(-1),
33 external_stencil_test_enabled_(false),
34 weak_ptr_factory_(this) {
37 OutputSurface::OutputSurface(
38 const scoped_refptr<ContextProvider>& context_provider)
39 : OutputSurface(context_provider, nullptr, nullptr) {
42 OutputSurface::OutputSurface(
43 const scoped_refptr<ContextProvider>& context_provider,
44 const scoped_refptr<ContextProvider>& worker_context_provider)
45 : OutputSurface(context_provider, worker_context_provider, nullptr) {
48 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
49 : OutputSurface(nullptr, nullptr, software_device.Pass()) {
52 OutputSurface::OutputSurface(
53 const scoped_refptr<ContextProvider>& context_provider,
54 scoped_ptr<SoftwareOutputDevice> software_device)
55 : OutputSurface(context_provider, nullptr, software_device.Pass()) {
58 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
59 base::TimeDelta interval) {
60 TRACE_EVENT2("cc",
61 "OutputSurface::CommitVSyncParameters",
62 "timebase",
63 (timebase - base::TimeTicks()).InSecondsF(),
64 "interval",
65 interval.InSecondsF());
66 client_->CommitVSyncParameters(timebase, interval);
69 // Forwarded to OutputSurfaceClient
70 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
71 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
72 client_->SetNeedsRedrawRect(damage_rect);
75 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
76 client_->ReclaimResources(ack);
79 void OutputSurface::DidLoseOutputSurface() {
80 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
81 client_->DidLoseOutputSurface();
84 void OutputSurface::SetExternalStencilTest(bool enabled) {
85 external_stencil_test_enabled_ = enabled;
88 void OutputSurface::SetExternalDrawConstraints(
89 const gfx::Transform& transform,
90 const gfx::Rect& viewport,
91 const gfx::Rect& clip,
92 const gfx::Rect& viewport_rect_for_tile_priority,
93 const gfx::Transform& transform_for_tile_priority,
94 bool resourceless_software_draw) {
95 client_->SetExternalDrawConstraints(transform,
96 viewport,
97 clip,
98 viewport_rect_for_tile_priority,
99 transform_for_tile_priority,
100 resourceless_software_draw);
103 OutputSurface::~OutputSurface() {
104 if (context_provider_.get()) {
105 context_provider_->SetLostContextCallback(
106 ContextProvider::LostContextCallback());
107 context_provider_->SetMemoryPolicyChangedCallback(
108 ContextProvider::MemoryPolicyChangedCallback());
110 if (worker_context_provider_.get()) {
111 worker_context_provider_->SetLostContextCallback(
112 ContextProvider::LostContextCallback());
116 bool OutputSurface::HasExternalStencilTest() const {
117 return external_stencil_test_enabled_;
120 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
121 DCHECK(client);
122 client_ = client;
123 bool success = true;
125 if (context_provider_.get()) {
126 success = context_provider_->BindToCurrentThread();
127 if (success) {
128 context_provider_->SetLostContextCallback(base::Bind(
129 &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
130 context_provider_->SetMemoryPolicyChangedCallback(
131 base::Bind(&OutputSurface::SetMemoryPolicy, base::Unretained(this)));
135 if (success && worker_context_provider_.get()) {
136 success = worker_context_provider_->BindToCurrentThread();
137 if (success) {
138 worker_context_provider_->SetupLock();
139 // The destructor resets the context lost callback, so base::Unretained
140 // is safe, as long as the worker threads stop using the context before
141 // the output surface is destroyed.
142 worker_context_provider_->SetLostContextCallback(base::Bind(
143 &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
147 if (!success)
148 client_ = NULL;
150 return success;
153 void OutputSurface::EnsureBackbuffer() {
154 if (software_device_)
155 software_device_->EnsureBackbuffer();
158 void OutputSurface::DiscardBackbuffer() {
159 if (context_provider_.get())
160 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
161 if (software_device_)
162 software_device_->DiscardBackbuffer();
165 void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
166 if (size == surface_size_ && scale_factor == device_scale_factor_)
167 return;
169 surface_size_ = size;
170 device_scale_factor_ = scale_factor;
171 if (context_provider_.get()) {
172 context_provider_->ContextGL()->ResizeCHROMIUM(
173 size.width(), size.height(), scale_factor);
175 if (software_device_)
176 software_device_->Resize(size, scale_factor);
179 gfx::Size OutputSurface::SurfaceSize() const {
180 return surface_size_;
183 void OutputSurface::BindFramebuffer() {
184 DCHECK(context_provider_.get());
185 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
188 void OutputSurface::PostSwapBuffersComplete() {
189 base::ThreadTaskRunnerHandle::Get()->PostTask(
190 FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete,
191 weak_ptr_factory_.GetWeakPtr()));
194 // We don't post tasks bound to the client directly since they might run
195 // after the OutputSurface has been destroyed.
196 void OutputSurface::OnSwapBuffersComplete() {
197 client_->DidSwapBuffersComplete();
200 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
201 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
202 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
203 // Just ignore the memory manager when it says to set the limit to zero
204 // bytes. This will happen when the memory manager thinks that the renderer
205 // is not visible (which the renderer knows better).
206 if (policy.bytes_limit_when_visible)
207 client_->SetMemoryPolicy(policy);
210 OverlayCandidateValidator* OutputSurface::GetOverlayCandidateValidator() const {
211 return nullptr;
214 void OutputSurface::SetWorkerContextShouldAggressivelyFreeResources(
215 bool aggressively_free_resources) {
216 TRACE_EVENT1("cc",
217 "OutputSurface::SetWorkerContextShouldAggressivelyFreeResources",
218 "aggressively_free_resources", aggressively_free_resources);
219 if (auto* context_provider = worker_context_provider()) {
220 // The context lock must be held while accessing the worker context.
221 base::AutoLock context_lock(*context_provider->GetLock());
223 // Allow context to bind to current thread.
224 context_provider->DetachFromThread();
226 if (aggressively_free_resources) {
227 context_provider->DeleteCachedResources();
230 if (auto* context_support = context_provider->ContextSupport()) {
231 context_support->SetAggressivelyFreeResources(
232 aggressively_free_resources);
235 // Allow context to bind to other threads.
236 context_provider->DetachFromThread();
240 bool OutputSurface::SurfaceIsSuspendForRecycle() const {
241 return false;
244 } // namespace cc