IndexedDB: Protect against use-after-free in ChainedBlobWriter.
[chromium-blink-merge.git] / cc / output / output_surface.cc
blob670578ad6b0cb32f4fd908dbe5cf1e3603b4ee62
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/gles2_interface.h"
16 #include "ui/gfx/geometry/rect.h"
17 #include "ui/gfx/geometry/size.h"
20 namespace cc {
22 OutputSurface::OutputSurface(
23 const scoped_refptr<ContextProvider>& context_provider,
24 const scoped_refptr<ContextProvider>& worker_context_provider,
25 scoped_ptr<SoftwareOutputDevice> software_device)
26 : client_(NULL),
27 context_provider_(context_provider),
28 worker_context_provider_(worker_context_provider),
29 software_device_(software_device.Pass()),
30 device_scale_factor_(-1),
31 external_stencil_test_enabled_(false),
32 weak_ptr_factory_(this) {
35 OutputSurface::OutputSurface(
36 const scoped_refptr<ContextProvider>& context_provider)
37 : OutputSurface(context_provider, nullptr, nullptr) {
40 OutputSurface::OutputSurface(
41 const scoped_refptr<ContextProvider>& context_provider,
42 const scoped_refptr<ContextProvider>& worker_context_provider)
43 : OutputSurface(context_provider, worker_context_provider, nullptr) {
46 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
47 : OutputSurface(nullptr, nullptr, software_device.Pass()) {
50 OutputSurface::OutputSurface(
51 const scoped_refptr<ContextProvider>& context_provider,
52 scoped_ptr<SoftwareOutputDevice> software_device)
53 : OutputSurface(context_provider, nullptr, software_device.Pass()) {
56 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
57 base::TimeDelta interval) {
58 TRACE_EVENT2("cc",
59 "OutputSurface::CommitVSyncParameters",
60 "timebase",
61 (timebase - base::TimeTicks()).InSecondsF(),
62 "interval",
63 interval.InSecondsF());
64 client_->CommitVSyncParameters(timebase, interval);
67 // Forwarded to OutputSurfaceClient
68 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
69 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
70 client_->SetNeedsRedrawRect(damage_rect);
73 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
74 client_->ReclaimResources(ack);
77 void OutputSurface::DidLoseOutputSurface() {
78 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
79 client_->DidLoseOutputSurface();
82 void OutputSurface::SetExternalStencilTest(bool enabled) {
83 external_stencil_test_enabled_ = enabled;
86 void OutputSurface::SetExternalDrawConstraints(
87 const gfx::Transform& transform,
88 const gfx::Rect& viewport,
89 const gfx::Rect& clip,
90 const gfx::Rect& viewport_rect_for_tile_priority,
91 const gfx::Transform& transform_for_tile_priority,
92 bool resourceless_software_draw) {
93 client_->SetExternalDrawConstraints(transform,
94 viewport,
95 clip,
96 viewport_rect_for_tile_priority,
97 transform_for_tile_priority,
98 resourceless_software_draw);
101 OutputSurface::~OutputSurface() {
102 if (context_provider_.get()) {
103 context_provider_->SetLostContextCallback(
104 ContextProvider::LostContextCallback());
105 context_provider_->SetMemoryPolicyChangedCallback(
106 ContextProvider::MemoryPolicyChangedCallback());
108 if (worker_context_provider_.get()) {
109 worker_context_provider_->SetLostContextCallback(
110 ContextProvider::LostContextCallback());
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 context_provider_->SetLostContextCallback(base::Bind(
127 &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
128 context_provider_->SetMemoryPolicyChangedCallback(
129 base::Bind(&OutputSurface::SetMemoryPolicy, base::Unretained(this)));
133 if (success && worker_context_provider_.get()) {
134 success = worker_context_provider_->BindToCurrentThread();
135 if (success) {
136 worker_context_provider_->SetupLock();
137 // The destructor resets the context lost callback, so base::Unretained
138 // is safe, as long as the worker threads stop using the context before
139 // the output surface is destroyed.
140 worker_context_provider_->SetLostContextCallback(base::Bind(
141 &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
145 if (!success)
146 client_ = NULL;
148 return success;
151 void OutputSurface::EnsureBackbuffer() {
152 if (software_device_)
153 software_device_->EnsureBackbuffer();
156 void OutputSurface::DiscardBackbuffer() {
157 if (context_provider_.get())
158 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
159 if (software_device_)
160 software_device_->DiscardBackbuffer();
163 void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
164 if (size == surface_size_ && scale_factor == device_scale_factor_)
165 return;
167 surface_size_ = size;
168 device_scale_factor_ = scale_factor;
169 if (context_provider_.get()) {
170 context_provider_->ContextGL()->ResizeCHROMIUM(
171 size.width(), size.height(), scale_factor);
173 if (software_device_)
174 software_device_->Resize(size, scale_factor);
177 gfx::Size OutputSurface::SurfaceSize() const {
178 return surface_size_;
181 void OutputSurface::BindFramebuffer() {
182 DCHECK(context_provider_.get());
183 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
186 void OutputSurface::PostSwapBuffersComplete() {
187 base::ThreadTaskRunnerHandle::Get()->PostTask(
188 FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete,
189 weak_ptr_factory_.GetWeakPtr()));
192 // We don't post tasks bound to the client directly since they might run
193 // after the OutputSurface has been destroyed.
194 void OutputSurface::OnSwapBuffersComplete() {
195 client_->DidSwapBuffersComplete();
198 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
199 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
200 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
201 // Just ignore the memory manager when it says to set the limit to zero
202 // bytes. This will happen when the memory manager thinks that the renderer
203 // is not visible (which the renderer knows better).
204 if (policy.bytes_limit_when_visible)
205 client_->SetMemoryPolicy(policy);
208 OverlayCandidateValidator* OutputSurface::GetOverlayCandidateValidator() const {
209 return nullptr;
212 } // namespace cc