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/debug/trace_event.h"
9 #include "base/message_loop/message_loop.h"
10 #include "cc/output/managed_memory_policy.h"
11 #include "cc/output/output_surface_client.h"
12 #include "gpu/GLES2/gl2extchromium.h"
13 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/geometry/size.h"
20 OutputSurface::OutputSurface(
21 const scoped_refptr
<ContextProvider
>& context_provider
)
23 context_provider_(context_provider
),
24 device_scale_factor_(-1),
25 external_stencil_test_enabled_(false),
26 weak_ptr_factory_(this) {
29 OutputSurface::OutputSurface(scoped_ptr
<SoftwareOutputDevice
> software_device
)
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 scoped_ptr
<SoftwareOutputDevice
> software_device
)
41 context_provider_(context_provider
),
42 software_device_(software_device
.Pass()),
43 device_scale_factor_(-1),
44 external_stencil_test_enabled_(false),
45 weak_ptr_factory_(this) {
48 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase
,
49 base::TimeDelta interval
) {
51 "OutputSurface::CommitVSyncParameters",
53 (timebase
- base::TimeTicks()).InSecondsF(),
55 interval
.InSecondsF());
56 client_
->CommitVSyncParameters(timebase
, interval
);
59 // Forwarded to OutputSurfaceClient
60 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect
& damage_rect
) {
61 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
62 client_
->SetNeedsRedrawRect(damage_rect
);
65 void OutputSurface::ReclaimResources(const CompositorFrameAck
* ack
) {
66 client_
->ReclaimResources(ack
);
69 void OutputSurface::DidLoseOutputSurface() {
70 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
71 client_
->DidLoseOutputSurface();
74 void OutputSurface::SetExternalStencilTest(bool enabled
) {
75 external_stencil_test_enabled_
= enabled
;
78 void OutputSurface::SetExternalDrawConstraints(
79 const gfx::Transform
& transform
,
80 const gfx::Rect
& viewport
,
81 const gfx::Rect
& clip
,
82 const gfx::Rect
& viewport_rect_for_tile_priority
,
83 const gfx::Transform
& transform_for_tile_priority
,
84 bool resourceless_software_draw
) {
85 client_
->SetExternalDrawConstraints(transform
,
88 viewport_rect_for_tile_priority
,
89 transform_for_tile_priority
,
90 resourceless_software_draw
);
93 OutputSurface::~OutputSurface() {
97 bool OutputSurface::HasExternalStencilTest() const {
98 return external_stencil_test_enabled_
;
101 bool OutputSurface::BindToClient(OutputSurfaceClient
* client
) {
106 if (context_provider_
.get()) {
107 success
= context_provider_
->BindToCurrentThread();
118 bool OutputSurface::InitializeAndSetContext3d(
119 scoped_refptr
<ContextProvider
> context_provider
) {
120 DCHECK(!context_provider_
.get());
121 DCHECK(context_provider
.get());
124 bool success
= false;
125 if (context_provider
->BindToCurrentThread()) {
126 context_provider_
= context_provider
;
128 client_
->DeferredInitialize();
138 void OutputSurface::ReleaseGL() {
140 DCHECK(context_provider_
.get());
141 client_
->ReleaseGL();
142 DCHECK(!context_provider_
.get());
145 void OutputSurface::SetUpContext3d() {
146 DCHECK(context_provider_
.get());
149 context_provider_
->SetLostContextCallback(
150 base::Bind(&OutputSurface::DidLoseOutputSurface
,
151 base::Unretained(this)));
152 context_provider_
->SetMemoryPolicyChangedCallback(
153 base::Bind(&OutputSurface::SetMemoryPolicy
,
154 base::Unretained(this)));
157 void OutputSurface::ReleaseContextProvider() {
159 DCHECK(context_provider_
.get());
163 void OutputSurface::ResetContext3d() {
164 if (context_provider_
.get()) {
165 context_provider_
->SetLostContextCallback(
166 ContextProvider::LostContextCallback());
167 context_provider_
->SetMemoryPolicyChangedCallback(
168 ContextProvider::MemoryPolicyChangedCallback());
170 context_provider_
= NULL
;
173 void OutputSurface::EnsureBackbuffer() {
174 if (software_device_
)
175 software_device_
->EnsureBackbuffer();
178 void OutputSurface::DiscardBackbuffer() {
179 if (context_provider_
.get())
180 context_provider_
->ContextGL()->DiscardBackbufferCHROMIUM();
181 if (software_device_
)
182 software_device_
->DiscardBackbuffer();
185 void OutputSurface::Reshape(const gfx::Size
& size
, float scale_factor
) {
186 if (size
== surface_size_
&& scale_factor
== device_scale_factor_
)
189 surface_size_
= size
;
190 device_scale_factor_
= scale_factor
;
191 if (context_provider_
.get()) {
192 context_provider_
->ContextGL()->ResizeCHROMIUM(
193 size
.width(), size
.height(), scale_factor
);
195 if (software_device_
)
196 software_device_
->Resize(size
, scale_factor
);
199 gfx::Size
OutputSurface::SurfaceSize() const {
200 return surface_size_
;
203 void OutputSurface::BindFramebuffer() {
204 DCHECK(context_provider_
.get());
205 context_provider_
->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER
, 0);
208 void OutputSurface::PostSwapBuffersComplete() {
209 base::MessageLoop::current()->PostTask(
211 base::Bind(&OutputSurface::OnSwapBuffersComplete
,
212 weak_ptr_factory_
.GetWeakPtr()));
215 // We don't post tasks bound to the client directly since they might run
216 // after the OutputSurface has been destroyed.
217 void OutputSurface::OnSwapBuffersComplete() {
218 client_
->DidSwapBuffersComplete();
221 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy
& policy
) {
222 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
223 "bytes_limit_when_visible", policy
.bytes_limit_when_visible
);
224 // Just ignore the memory manager when it says to set the limit to zero
225 // bytes. This will happen when the memory manager thinks that the renderer
226 // is not visible (which the renderer knows better).
227 if (policy
.bytes_limit_when_visible
)
228 client_
->SetMemoryPolicy(policy
);