Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / cc / output / output_surface.cc
blob5014fc06c8885a4d8e958c82a395bef3e2413be1
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/core/SkTraceMemoryDump.h"
18 #include "third_party/skia/include/gpu/GrContext.h"
19 #include "ui/gfx/geometry/rect.h"
20 #include "ui/gfx/geometry/size.h"
21 #include "ui/gl/trace_util.h"
23 class SkDiscardableMemory;
25 namespace cc {
27 namespace {
29 // Constants used by SkiaGpuTraceMemoryDump to identify different memory types.
30 const char* kGLTextureBackingType = "gl_texture";
31 const char* kGLBufferBackingType = "gl_buffer";
32 const char* kGLRenderbufferBackingType = "gl_renderbuffer";
34 // Derives from SkTraceMemoryDump and implements graphics specific memory
35 // backing functionality.
36 class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump {
37 public:
38 // This should never outlive the provided ProcessMemoryDump, as it should
39 // always be scoped to a single OnMemoryDump funciton call.
40 explicit SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
41 uint64_t share_group_tracing_guid)
42 : pmd_(pmd), share_group_tracing_guid_(share_group_tracing_guid) {}
44 // Overridden from SkTraceMemoryDump:
45 void dumpNumericValue(const char* dump_name,
46 const char* value_name,
47 const char* units,
48 uint64_t value) override {
49 auto dump = GetOrCreateAllocatorDump(dump_name);
50 dump->AddScalar(value_name, units, value);
53 void setMemoryBacking(const char* dump_name,
54 const char* backing_type,
55 const char* backing_object_id) override {
56 const uint64 tracing_process_id =
57 base::trace_event::MemoryDumpManager::GetInstance()
58 ->GetTracingProcessId();
60 // For uniformity, skia provides this value as a string. Convert back to a
61 // uint32_t.
62 uint32_t gl_id =
63 std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */);
65 // Populated in if statements below.
66 base::trace_event::MemoryAllocatorDumpGuid guid;
68 if (strcmp(backing_type, kGLTextureBackingType) == 0) {
69 guid = gfx::GetGLTextureClientGUIDForTracing(share_group_tracing_guid_,
70 gl_id);
71 } else if (strcmp(backing_type, kGLBufferBackingType) == 0) {
72 guid = gfx::GetGLBufferGUIDForTracing(tracing_process_id, gl_id);
73 } else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) {
74 guid = gfx::GetGLRenderbufferGUIDForTracing(tracing_process_id, gl_id);
77 if (!guid.empty()) {
78 pmd_->CreateSharedGlobalAllocatorDump(guid);
80 auto* dump = GetOrCreateAllocatorDump(dump_name);
82 const int kImportance = 2;
83 pmd_->AddOwnershipEdge(dump->guid(), guid, kImportance);
87 void setDiscardableMemoryBacking(
88 const char* dump_name,
89 const SkDiscardableMemory& discardable_memory_object) override {
90 // We don't use this class for dumping discardable memory.
91 NOTREACHED();
94 private:
95 // Helper to create allocator dumps.
96 base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
97 const char* dump_name) {
98 auto dump = pmd_->GetAllocatorDump(dump_name);
99 if (!dump)
100 dump = pmd_->CreateAllocatorDump(dump_name);
101 return dump;
104 base::trace_event::ProcessMemoryDump* pmd_;
105 uint64_t share_group_tracing_guid_;
107 DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump);
110 } // namespace
112 OutputSurface::OutputSurface(
113 const scoped_refptr<ContextProvider>& context_provider,
114 const scoped_refptr<ContextProvider>& worker_context_provider,
115 scoped_ptr<SoftwareOutputDevice> software_device)
116 : client_(NULL),
117 context_provider_(context_provider),
118 worker_context_provider_(worker_context_provider),
119 software_device_(software_device.Pass()),
120 device_scale_factor_(-1),
121 external_stencil_test_enabled_(false),
122 weak_ptr_factory_(this) {
125 OutputSurface::OutputSurface(
126 const scoped_refptr<ContextProvider>& context_provider)
127 : OutputSurface(context_provider, nullptr, nullptr) {
130 OutputSurface::OutputSurface(
131 const scoped_refptr<ContextProvider>& context_provider,
132 const scoped_refptr<ContextProvider>& worker_context_provider)
133 : OutputSurface(context_provider, worker_context_provider, nullptr) {
136 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
137 : OutputSurface(nullptr, nullptr, software_device.Pass()) {
140 OutputSurface::OutputSurface(
141 const scoped_refptr<ContextProvider>& context_provider,
142 scoped_ptr<SoftwareOutputDevice> software_device)
143 : OutputSurface(context_provider, nullptr, software_device.Pass()) {
146 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
147 base::TimeDelta interval) {
148 TRACE_EVENT2("cc",
149 "OutputSurface::CommitVSyncParameters",
150 "timebase",
151 (timebase - base::TimeTicks()).InSecondsF(),
152 "interval",
153 interval.InSecondsF());
154 client_->CommitVSyncParameters(timebase, interval);
157 // Forwarded to OutputSurfaceClient
158 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
159 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
160 client_->SetNeedsRedrawRect(damage_rect);
163 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
164 client_->ReclaimResources(ack);
167 void OutputSurface::DidLoseOutputSurface() {
168 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
169 client_->DidLoseOutputSurface();
172 void OutputSurface::SetExternalStencilTest(bool enabled) {
173 external_stencil_test_enabled_ = enabled;
176 void OutputSurface::SetExternalDrawConstraints(
177 const gfx::Transform& transform,
178 const gfx::Rect& viewport,
179 const gfx::Rect& clip,
180 const gfx::Rect& viewport_rect_for_tile_priority,
181 const gfx::Transform& transform_for_tile_priority,
182 bool resourceless_software_draw) {
183 client_->SetExternalDrawConstraints(transform,
184 viewport,
185 clip,
186 viewport_rect_for_tile_priority,
187 transform_for_tile_priority,
188 resourceless_software_draw);
191 OutputSurface::~OutputSurface() {
192 // Unregister any dump provider. Safe to call (no-op) if we have not yet
193 // registered.
194 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
195 this);
197 if (context_provider_.get()) {
198 context_provider_->SetLostContextCallback(
199 ContextProvider::LostContextCallback());
200 context_provider_->SetMemoryPolicyChangedCallback(
201 ContextProvider::MemoryPolicyChangedCallback());
205 bool OutputSurface::HasExternalStencilTest() const {
206 return external_stencil_test_enabled_;
209 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
210 DCHECK(client);
211 client_ = client;
212 bool success = true;
214 if (context_provider_.get()) {
215 success = context_provider_->BindToCurrentThread();
216 if (success) {
217 context_provider_->SetLostContextCallback(base::Bind(
218 &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
219 context_provider_->SetMemoryPolicyChangedCallback(
220 base::Bind(&OutputSurface::SetMemoryPolicy, base::Unretained(this)));
224 if (success && worker_context_provider_.get()) {
225 success = worker_context_provider_->BindToCurrentThread();
226 if (success)
227 worker_context_provider_->SetupLock();
230 if (!success)
231 client_ = NULL;
233 // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
234 // Don't register a dump provider in these cases.
235 // TODO(ericrk): Get this working in Android Webview. crbug.com/517156
236 if (base::ThreadTaskRunnerHandle::IsSet()) {
237 // Now that we are on the context thread, register a dump provider with this
238 // thread's task runner. This will overwrite any previous dump provider
239 // registered.
240 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
241 this, base::ThreadTaskRunnerHandle::Get());
244 return success;
247 void OutputSurface::EnsureBackbuffer() {
248 if (software_device_)
249 software_device_->EnsureBackbuffer();
252 void OutputSurface::DiscardBackbuffer() {
253 if (context_provider_.get())
254 context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
255 if (software_device_)
256 software_device_->DiscardBackbuffer();
259 void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
260 if (size == surface_size_ && scale_factor == device_scale_factor_)
261 return;
263 surface_size_ = size;
264 device_scale_factor_ = scale_factor;
265 if (context_provider_.get()) {
266 context_provider_->ContextGL()->ResizeCHROMIUM(
267 size.width(), size.height(), scale_factor);
269 if (software_device_)
270 software_device_->Resize(size, scale_factor);
273 void OutputSurface::BindFramebuffer() {
274 DCHECK(context_provider_.get());
275 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
278 void OutputSurface::PostSwapBuffersComplete() {
279 base::ThreadTaskRunnerHandle::Get()->PostTask(
280 FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete,
281 weak_ptr_factory_.GetWeakPtr()));
284 // We don't post tasks bound to the client directly since they might run
285 // after the OutputSurface has been destroyed.
286 void OutputSurface::OnSwapBuffersComplete() {
287 client_->DidSwapBuffersComplete();
290 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
291 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
292 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
293 // Just ignore the memory manager when it says to set the limit to zero
294 // bytes. This will happen when the memory manager thinks that the renderer
295 // is not visible (which the renderer knows better).
296 if (policy.bytes_limit_when_visible)
297 client_->SetMemoryPolicy(policy);
300 OverlayCandidateValidator* OutputSurface::GetOverlayCandidateValidator() const {
301 return nullptr;
304 unsigned OutputSurface::GetOverlayTextureId() const {
305 return 0;
308 void OutputSurface::SetWorkerContextShouldAggressivelyFreeResources(
309 bool aggressively_free_resources) {
310 TRACE_EVENT1("cc",
311 "OutputSurface::SetWorkerContextShouldAggressivelyFreeResources",
312 "aggressively_free_resources", aggressively_free_resources);
313 if (auto* context_provider = worker_context_provider()) {
314 ContextProvider::ScopedContextLock scoped_context(context_provider);
316 if (aggressively_free_resources) {
317 context_provider->DeleteCachedResources();
320 if (auto* context_support = context_provider->ContextSupport()) {
321 context_support->SetAggressivelyFreeResources(
322 aggressively_free_resources);
327 bool OutputSurface::SurfaceIsSuspendForRecycle() const {
328 return false;
331 bool OutputSurface::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
332 base::trace_event::ProcessMemoryDump* pmd) {
333 if (auto* context_provider = this->context_provider()) {
334 // No need to lock, main context provider is not shared.
335 if (auto* gr_context = context_provider->GrContext()) {
336 SkiaGpuTraceMemoryDump trace_memory_dump(
337 pmd, context_provider->ContextSupport()->ShareGroupTracingGUID());
338 gr_context->dumpMemoryStatistics(&trace_memory_dump);
341 if (auto* context_provider = worker_context_provider()) {
342 ContextProvider::ScopedContextLock scoped_context(context_provider);
344 if (auto* gr_context = context_provider->GrContext()) {
345 SkiaGpuTraceMemoryDump trace_memory_dump(
346 pmd, context_provider->ContextSupport()->ShareGroupTracingGUID());
347 gr_context->dumpMemoryStatistics(&trace_memory_dump);
351 return true;
354 } // namespace cc