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"
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"
24 OutputSurface::OutputSurface(
25 const scoped_refptr
<ContextProvider
>& context_provider
,
26 const scoped_refptr
<ContextProvider
>& worker_context_provider
,
27 scoped_ptr
<SoftwareOutputDevice
> software_device
)
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
) {
61 "OutputSurface::CommitVSyncParameters",
63 (timebase
- base::TimeTicks()).InSecondsF(),
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
,
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());
112 bool OutputSurface::HasExternalStencilTest() const {
113 return external_stencil_test_enabled_
;
116 bool OutputSurface::BindToClient(OutputSurfaceClient
* client
) {
121 if (context_provider_
.get()) {
122 success
= context_provider_
->BindToCurrentThread();
124 context_provider_
->SetLostContextCallback(base::Bind(
125 &OutputSurface::DidLoseOutputSurface
, base::Unretained(this)));
126 context_provider_
->SetMemoryPolicyChangedCallback(
127 base::Bind(&OutputSurface::SetMemoryPolicy
, base::Unretained(this)));
131 if (success
&& worker_context_provider_
.get()) {
132 success
= worker_context_provider_
->BindToCurrentThread();
134 worker_context_provider_
->SetupLock();
143 void OutputSurface::EnsureBackbuffer() {
144 if (software_device_
)
145 software_device_
->EnsureBackbuffer();
148 void OutputSurface::DiscardBackbuffer() {
149 if (context_provider_
.get())
150 context_provider_
->ContextGL()->DiscardBackbufferCHROMIUM();
151 if (software_device_
)
152 software_device_
->DiscardBackbuffer();
155 void OutputSurface::Reshape(const gfx::Size
& size
, float scale_factor
) {
156 if (size
== surface_size_
&& scale_factor
== device_scale_factor_
)
159 surface_size_
= size
;
160 device_scale_factor_
= scale_factor
;
161 if (context_provider_
.get()) {
162 context_provider_
->ContextGL()->ResizeCHROMIUM(
163 size
.width(), size
.height(), scale_factor
);
165 if (software_device_
)
166 software_device_
->Resize(size
, scale_factor
);
169 void OutputSurface::BindFramebuffer() {
170 DCHECK(context_provider_
.get());
171 context_provider_
->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER
, 0);
174 void OutputSurface::PostSwapBuffersComplete() {
175 base::ThreadTaskRunnerHandle::Get()->PostTask(
176 FROM_HERE
, base::Bind(&OutputSurface::OnSwapBuffersComplete
,
177 weak_ptr_factory_
.GetWeakPtr()));
180 // We don't post tasks bound to the client directly since they might run
181 // after the OutputSurface has been destroyed.
182 void OutputSurface::OnSwapBuffersComplete() {
183 client_
->DidSwapBuffersComplete();
186 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy
& policy
) {
187 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
188 "bytes_limit_when_visible", policy
.bytes_limit_when_visible
);
189 // Just ignore the memory manager when it says to set the limit to zero
190 // bytes. This will happen when the memory manager thinks that the renderer
191 // is not visible (which the renderer knows better).
192 if (policy
.bytes_limit_when_visible
)
193 client_
->SetMemoryPolicy(policy
);
196 OverlayCandidateValidator
* OutputSurface::GetOverlayCandidateValidator() const {
200 unsigned OutputSurface::GetOverlayTextureId() const {
204 void OutputSurface::SetWorkerContextShouldAggressivelyFreeResources(
205 bool aggressively_free_resources
) {
207 "OutputSurface::SetWorkerContextShouldAggressivelyFreeResources",
208 "aggressively_free_resources", aggressively_free_resources
);
209 if (auto* context_provider
= worker_context_provider()) {
210 ContextProvider::ScopedContextLock
scoped_context(context_provider
);
212 if (aggressively_free_resources
) {
213 context_provider
->DeleteCachedResources();
216 if (auto* context_support
= context_provider
->ContextSupport()) {
217 context_support
->SetAggressivelyFreeResources(
218 aggressively_free_resources
);
223 bool OutputSurface::SurfaceIsSuspendForRecycle() const {