Remove Dr. Memory suppression for now-fixed null deref.
[chromium-blink-merge.git] / cc / output / output_surface.cc
blob2dd5a213551ae3783d2521e4ad9074783c26b111
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/GLES2/gl2extchromium.h"
25 #include "gpu/command_buffer/client/context_support.h"
26 #include "gpu/command_buffer/client/gles2_interface.h"
27 #include "ui/gfx/frame_time.h"
28 #include "ui/gfx/geometry/rect.h"
29 #include "ui/gfx/geometry/size.h"
31 using std::set;
32 using std::string;
33 using std::vector;
35 namespace cc {
37 OutputSurface::OutputSurface(
38 const scoped_refptr<ContextProvider>& context_provider)
39 : client_(NULL),
40 context_provider_(context_provider),
41 device_scale_factor_(-1),
42 external_stencil_test_enabled_(false),
43 weak_ptr_factory_(this) {
46 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
47 : client_(NULL),
48 software_device_(software_device.Pass()),
49 device_scale_factor_(-1),
50 external_stencil_test_enabled_(false),
51 weak_ptr_factory_(this) {
54 OutputSurface::OutputSurface(
55 const scoped_refptr<ContextProvider>& context_provider,
56 scoped_ptr<SoftwareOutputDevice> software_device)
57 : client_(NULL),
58 context_provider_(context_provider),
59 software_device_(software_device.Pass()),
60 device_scale_factor_(-1),
61 external_stencil_test_enabled_(false),
62 weak_ptr_factory_(this) {
65 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
66 base::TimeDelta interval) {
67 TRACE_EVENT2("cc",
68 "OutputSurface::CommitVSyncParameters",
69 "timebase",
70 (timebase - base::TimeTicks()).InSecondsF(),
71 "interval",
72 interval.InSecondsF());
73 client_->CommitVSyncParameters(timebase, interval);
76 // Forwarded to OutputSurfaceClient
77 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
78 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
79 client_->SetNeedsRedrawRect(damage_rect);
82 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
83 client_->ReclaimResources(ack);
86 void OutputSurface::DidLoseOutputSurface() {
87 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
88 client_->DidLoseOutputSurface();
91 void OutputSurface::SetExternalStencilTest(bool enabled) {
92 external_stencil_test_enabled_ = enabled;
95 void OutputSurface::SetExternalDrawConstraints(
96 const gfx::Transform& transform,
97 const gfx::Rect& viewport,
98 const gfx::Rect& clip,
99 const gfx::Rect& viewport_rect_for_tile_priority,
100 const gfx::Transform& transform_for_tile_priority,
101 bool resourceless_software_draw) {
102 client_->SetExternalDrawConstraints(transform,
103 viewport,
104 clip,
105 viewport_rect_for_tile_priority,
106 transform_for_tile_priority,
107 resourceless_software_draw);
110 OutputSurface::~OutputSurface() {
111 ResetContext3d();
114 bool OutputSurface::HasExternalStencilTest() const {
115 return external_stencil_test_enabled_;
118 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
119 DCHECK(client);
120 client_ = client;
121 bool success = true;
123 if (context_provider_.get()) {
124 success = context_provider_->BindToCurrentThread();
125 if (success)
126 SetUpContext3d();
129 if (!success)
130 client_ = NULL;
132 return success;
135 bool OutputSurface::InitializeAndSetContext3d(
136 scoped_refptr<ContextProvider> context_provider) {
137 DCHECK(!context_provider_.get());
138 DCHECK(context_provider.get());
139 DCHECK(client_);
141 bool success = false;
142 if (context_provider->BindToCurrentThread()) {
143 context_provider_ = context_provider;
144 SetUpContext3d();
145 client_->DeferredInitialize();
146 success = true;
149 if (!success)
150 ResetContext3d();
152 return success;
155 void OutputSurface::ReleaseGL() {
156 DCHECK(client_);
157 DCHECK(context_provider_.get());
158 client_->ReleaseGL();
159 DCHECK(!context_provider_.get());
162 void OutputSurface::SetUpContext3d() {
163 DCHECK(context_provider_.get());
164 DCHECK(client_);
166 context_provider_->SetLostContextCallback(
167 base::Bind(&OutputSurface::DidLoseOutputSurface,
168 base::Unretained(this)));
169 context_provider_->SetMemoryPolicyChangedCallback(
170 base::Bind(&OutputSurface::SetMemoryPolicy,
171 base::Unretained(this)));
174 void OutputSurface::ReleaseContextProvider() {
175 DCHECK(client_);
176 DCHECK(context_provider_.get());
177 ResetContext3d();
180 void OutputSurface::ResetContext3d() {
181 if (context_provider_.get()) {
182 context_provider_->SetLostContextCallback(
183 ContextProvider::LostContextCallback());
184 context_provider_->SetMemoryPolicyChangedCallback(
185 ContextProvider::MemoryPolicyChangedCallback());
187 context_provider_ = NULL;
190 void OutputSurface::EnsureBackbuffer() {
191 if (software_device_)
192 software_device_->EnsureBackbuffer();
195 void OutputSurface::DiscardBackbuffer() {
196 if (context_provider_.get())
197 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
198 if (software_device_)
199 software_device_->DiscardBackbuffer();
202 void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
203 if (size == surface_size_ && scale_factor == device_scale_factor_)
204 return;
206 surface_size_ = size;
207 device_scale_factor_ = scale_factor;
208 if (context_provider_.get()) {
209 context_provider_->ContextGL()->ResizeCHROMIUM(
210 size.width(), size.height(), scale_factor);
212 if (software_device_)
213 software_device_->Resize(size, scale_factor);
216 gfx::Size OutputSurface::SurfaceSize() const {
217 return surface_size_;
220 void OutputSurface::BindFramebuffer() {
221 DCHECK(context_provider_.get());
222 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
225 void OutputSurface::SwapBuffers(CompositorFrame* frame) {
226 if (frame->software_frame_data) {
227 PostSwapBuffersComplete();
228 client_->DidSwapBuffers();
229 return;
232 DCHECK(context_provider_.get());
233 DCHECK(frame->gl_frame_data);
235 if (frame->gl_frame_data->sub_buffer_rect ==
236 gfx::Rect(frame->gl_frame_data->size)) {
237 context_provider_->ContextSupport()->Swap();
238 } else {
239 context_provider_->ContextSupport()->PartialSwapBuffers(
240 frame->gl_frame_data->sub_buffer_rect);
242 uint32_t sync_point =
243 context_provider_->ContextGL()->InsertSyncPointCHROMIUM();
244 context_provider_->ContextSupport()->SignalSyncPoint(
245 sync_point,
246 base::Bind(&OutputSurface::OnSwapBuffersComplete,
247 weak_ptr_factory_.GetWeakPtr()));
249 client_->DidSwapBuffers();
252 void OutputSurface::PostSwapBuffersComplete() {
253 base::MessageLoop::current()->PostTask(
254 FROM_HERE,
255 base::Bind(&OutputSurface::OnSwapBuffersComplete,
256 weak_ptr_factory_.GetWeakPtr()));
259 // We don't post tasks bound to the client directly since they might run
260 // after the OutputSurface has been destroyed.
261 void OutputSurface::OnSwapBuffersComplete() {
262 client_->DidSwapBuffersComplete();
265 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
266 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
267 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
268 // Just ignore the memory manager when it says to set the limit to zero
269 // bytes. This will happen when the memory manager thinks that the renderer
270 // is not visible (which the renderer knows better).
271 if (policy.bytes_limit_when_visible)
272 client_->SetMemoryPolicy(policy);
275 } // namespace cc