blob: 294840be307e20f0315fc07ccd150fc10013e419 [file] [log] [blame]
[email protected]b95a2ee2014-06-01 12:25:391// Copyright 2014 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.
4
jbaumanf400ce532015-02-03 04:54:595#include "cc/surfaces/surface_display_output_surface.h"
[email protected]b95a2ee2014-06-01 12:25:396
jamesr9b8fda32015-03-16 19:11:057#include "base/bind.h"
[email protected]b95a2ee2014-06-01 12:25:398#include "cc/output/compositor_frame.h"
9#include "cc/surfaces/display.h"
10#include "cc/surfaces/surface.h"
danakj324faea2016-06-11 01:39:3111#include "cc/surfaces/surface_id_allocator.h"
[email protected]b95a2ee2014-06-01 12:25:3912#include "cc/surfaces/surface_manager.h"
13
jbaumanf400ce532015-02-03 04:54:5914namespace cc {
[email protected]b95a2ee2014-06-01 12:25:3915
16SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface(
jbaumanf400ce532015-02-03 04:54:5917 SurfaceManager* surface_manager,
danakj324faea2016-06-11 01:39:3118 SurfaceIdAllocator* surface_id_allocator,
19 Display* display,
vmpstr4065174a2016-03-16 20:44:0220 scoped_refptr<ContextProvider> context_provider,
21 scoped_refptr<ContextProvider> worker_context_provider)
22 : OutputSurface(std::move(context_provider),
hajimehoshiea85b9dc2016-05-25 09:52:3123 std::move(worker_context_provider),
24 nullptr),
danakj324faea2016-06-11 01:39:3125 surface_manager_(surface_manager),
26 surface_id_allocator_(surface_id_allocator),
27 display_(display),
28 factory_(surface_manager, this) {
29 DCHECK(thread_checker_.CalledOnValidThread());
[email protected]b95a2ee2014-06-01 12:25:3930 capabilities_.delegated_rendering = true;
jbaumane32b9232015-03-20 01:25:5431 capabilities_.adjust_deadline_for_parent = true;
jbauman9bfb1a52015-01-09 08:16:0332 capabilities_.can_force_reclaim_resources = true;
danakj324faea2016-06-11 01:39:3133
jbauman65182a32015-04-11 00:32:1234 // Display and SurfaceDisplayOutputSurface share a GL context, so sync
35 // points aren't needed when passing resources between them.
36 capabilities_.delegated_sync_points_required = false;
danakj324faea2016-06-11 01:39:3137 factory_.set_needs_sync_points(false);
[email protected]b95a2ee2014-06-01 12:25:3938}
39
dyenb52ecd962016-04-20 23:23:4440SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface(
41 SurfaceManager* surface_manager,
danakj324faea2016-06-11 01:39:3142 SurfaceIdAllocator* surface_id_allocator,
43 Display* display,
dyenb52ecd962016-04-20 23:23:4444 scoped_refptr<VulkanContextProvider> vulkan_context_provider)
hajimehoshiea85b9dc2016-05-25 09:52:3145 : OutputSurface(std::move(vulkan_context_provider)),
danakj324faea2016-06-11 01:39:3146 surface_manager_(surface_manager),
47 surface_id_allocator_(surface_id_allocator),
48 display_(display),
49 factory_(surface_manager, this) {
50 DCHECK(thread_checker_.CalledOnValidThread());
dyenb52ecd962016-04-20 23:23:4451 capabilities_.delegated_rendering = true;
52 capabilities_.adjust_deadline_for_parent = true;
53 capabilities_.can_force_reclaim_resources = true;
54}
55
[email protected]b95a2ee2014-06-01 12:25:3956SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() {
danakj324faea2016-06-11 01:39:3157 DCHECK(thread_checker_.CalledOnValidThread());
enne4e3c9d52016-03-09 00:25:1258 if (HasClient())
59 DetachFromClient();
[email protected]b95a2ee2014-06-01 12:25:3960}
61
fsamueld63137a2016-06-24 23:39:5162void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame frame) {
[email protected]b95a2ee2014-06-01 12:25:3963 gfx::Size frame_size =
fsamueld63137a2016-06-24 23:39:5164 frame.delegated_frame_data->render_pass_list.back()->output_rect.size();
danakj324faea2016-06-11 01:39:3165 if (frame_size.IsEmpty() || frame_size != last_swap_frame_size_) {
66 if (!delegated_surface_id_.is_null()) {
67 factory_.Destroy(delegated_surface_id_);
[email protected]cde792132014-07-02 06:52:4668 }
danakj324faea2016-06-11 01:39:3169 delegated_surface_id_ = surface_id_allocator_->GenerateId();
70 factory_.Create(delegated_surface_id_);
71 last_swap_frame_size_ = frame_size;
[email protected]cde792132014-07-02 06:52:4672 }
danakj324faea2016-06-11 01:39:3173 display_->SetSurfaceId(delegated_surface_id_,
fsamueld63137a2016-06-24 23:39:5174 frame.metadata.device_scale_factor);
[email protected]b95a2ee2014-06-01 12:25:3975
fsamuelcb87fbf2015-08-24 16:41:0176 factory_.SubmitCompositorFrame(
fsamuel5222b6c2016-06-29 00:36:5177 delegated_surface_id_, std::move(frame),
danakj014316e2016-08-04 18:40:2678 base::Bind(&SurfaceDisplayOutputSurface::DidDrawCallback,
jbauman878e9532014-08-23 22:10:2379 base::Unretained(this)));
[email protected]b95a2ee2014-06-01 12:25:3980}
81
jbaumanf400ce532015-02-03 04:54:5982bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) {
danakj324faea2016-06-11 01:39:3183 DCHECK(thread_checker_.CalledOnValidThread());
danakj4f26adf22016-06-16 19:38:2184
85 surface_manager_->RegisterSurfaceFactoryClient(
fsamuel278664272016-07-13 04:06:5986 surface_id_allocator_->client_id(), this);
danakj4f26adf22016-06-16 19:38:2187
danakj324faea2016-06-11 01:39:3188 if (!OutputSurface::BindToClient(client))
89 return false;
enne4e3c9d52016-03-09 00:25:1290
danakj324faea2016-06-11 01:39:3191 // We want the Display's output surface to hear about lost context, and since
92 // this shares a context with it, we should not be listening for lost context
93 // callbacks on the context here.
94 if (context_provider())
95 context_provider()->SetLostContextCallback(base::Closure());
96
jbaumana8c5cc92014-10-03 20:51:2397 // Avoid initializing GL context here, as this should be sharing the
98 // Display's context.
danakj516efc02016-07-14 23:24:0599 display_->Initialize(this, surface_manager_,
100 surface_id_allocator_->client_id());
danakj324faea2016-06-11 01:39:31101 return true;
jbaumana8c5cc92014-10-03 20:51:23102}
103
jbauman9bfb1a52015-01-09 08:16:03104void SurfaceDisplayOutputSurface::ForceReclaimResources() {
danakj324faea2016-06-11 01:39:31105 if (!delegated_surface_id_.is_null()) {
fsamuel5222b6c2016-06-29 00:36:51106 factory_.SubmitCompositorFrame(delegated_surface_id_, CompositorFrame(),
fsamuelcb87fbf2015-08-24 16:41:01107 SurfaceFactory::DrawCallback());
danakj324faea2016-06-11 01:39:31108 }
jbauman9bfb1a52015-01-09 08:16:03109}
110
enne4e3c9d52016-03-09 00:25:12111void SurfaceDisplayOutputSurface::DetachFromClient() {
112 DCHECK(HasClient());
113 // Unregister the SurfaceFactoryClient here instead of the dtor so that only
114 // one client is alive for this namespace at any given time.
danakj324faea2016-06-11 01:39:31115 surface_manager_->UnregisterSurfaceFactoryClient(
fsamuel278664272016-07-13 04:06:59116 surface_id_allocator_->client_id());
danakj324faea2016-06-11 01:39:31117 if (!delegated_surface_id_.is_null())
118 factory_.Destroy(delegated_surface_id_);
119
enne4e3c9d52016-03-09 00:25:12120 OutputSurface::DetachFromClient();
enne4e3c9d52016-03-09 00:25:12121}
122
danakja85bd242016-06-22 22:25:49123void SurfaceDisplayOutputSurface::BindFramebuffer() {
124 // This is a delegating output surface, no framebuffer/direct drawing support.
125 NOTREACHED();
126}
127
128uint32_t SurfaceDisplayOutputSurface::GetFramebufferCopyTextureFormat() {
129 // This is a delegating output surface, no framebuffer/direct drawing support.
130 NOTREACHED();
131 return 0;
132}
133
[email protected]387b59d2014-06-27 01:17:34134void SurfaceDisplayOutputSurface::ReturnResources(
jbaumanf400ce532015-02-03 04:54:59135 const ReturnedResourceArray& resources) {
[email protected]72728b12014-07-18 03:39:17136 if (client_)
fsamuelb62b78222016-07-15 01:14:14137 client_->ReclaimResources(resources);
[email protected]387b59d2014-06-27 01:17:34138}
139
brianderson877996b02015-10-20 20:35:31140void SurfaceDisplayOutputSurface::SetBeginFrameSource(
brianderson877996b02015-10-20 20:35:31141 BeginFrameSource* begin_frame_source) {
enne19c108582016-04-14 03:35:32142 DCHECK(client_);
143 client_->SetBeginFrameSource(begin_frame_source);
brianderson877996b02015-10-20 20:35:31144}
145
danakj324faea2016-06-11 01:39:31146void SurfaceDisplayOutputSurface::DisplayOutputSurfaceLost() {
147 output_surface_lost_ = true;
148 DidLoseOutputSurface();
149}
150
151void SurfaceDisplayOutputSurface::DisplaySetMemoryPolicy(
152 const ManagedMemoryPolicy& policy) {
153 SetMemoryPolicy(policy);
154}
155
danakj014316e2016-08-04 18:40:26156void SurfaceDisplayOutputSurface::DisplayWillDrawAndSwap(
157 bool will_draw_and_swap,
158 const RenderPassList& render_passes) {
159 // This notification is not relevant to our client outside of tests.
160}
161
162void SurfaceDisplayOutputSurface::DisplayDidDrawAndSwap() {
163 // This notification is not relevant to our client outside of tests. We
164 // unblock the client from DidDrawCallback() when the surface is going to
165 // be drawn.
166}
167
168void SurfaceDisplayOutputSurface::DidDrawCallback() {
danakj324faea2016-06-11 01:39:31169 // TODO(danakj): Why the lost check?
170 if (!output_surface_lost_)
jbauman6a2b78c72014-12-11 03:21:28171 client_->DidSwapBuffersComplete();
jbauman878e9532014-08-23 22:10:23172}
173
jbaumanf400ce532015-02-03 04:54:59174} // namespace cc