OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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 | |
5 #include "content/browser/compositor/mus_browser_compositor_output_surface.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "build/build_config.h" | |
10 #include "cc/output/compositor_frame.h" | |
11 #include "cc/output/compositor_frame_ack.h" | |
12 #include "cc/output/output_surface_client.h" | |
13 #include "cc/quads/render_pass.h" | |
14 #include "cc/quads/texture_draw_quad.h" | |
15 #include "components/display_compositor/compositor_overlay_candidate_validator.h " | |
16 #include "components/mus/common/gpu_service.h" | |
17 #include "components/mus/public/cpp/window.h" | |
18 #include "components/mus/public/cpp/window_surface.h" | |
19 #include "content/browser/compositor/reflector_impl.h" | |
20 #include "content/browser/compositor/reflector_texture.h" | |
21 #include "content/browser/renderer_host/render_widget_host_impl.h" | |
22 #include "content/common/gpu/client/context_provider_command_buffer.h" | |
23 #include "gpu/command_buffer/client/context_support.h" | |
24 #include "gpu/command_buffer/client/gles2_interface.h" | |
25 #include "gpu/ipc/client/command_buffer_proxy_impl.h" | |
26 #include "ui/views/mus/native_widget_mus.h" | |
27 #include "ui/views/mus/window_tree_host_mus.h" | |
28 | |
29 namespace content { | |
30 | |
31 MusBrowserCompositorOutputSurface::MusBrowserCompositorOutputSurface( | |
32 gpu::SurfaceHandle surface_handle, | |
33 scoped_refptr<ContextProviderCommandBuffer> context, | |
34 scoped_refptr<ui::CompositorVSyncManager> vsync_manager, | |
35 cc::SyntheticBeginFrameSource* begin_frame_source, | |
36 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> | |
37 overlay_candidate_validator) | |
38 : GpuBrowserCompositorOutputSurface(std::move(context), | |
39 std::move(vsync_manager), | |
40 begin_frame_source, | |
41 std::move(overlay_candidate_validator)), | |
42 mus_window_(nullptr) { | |
43 DCHECK(mus::GpuService::UseChromeGpuCommandBuffer()); | |
44 views::WindowTreeHostMus* window_tree_host = | |
45 static_cast<views::WindowTreeHostMus*>( | |
46 aura::WindowTreeHost::GetForAcceleratedWidget(surface_handle)); | |
47 mus_window_ = window_tree_host->native_widget()->window(); | |
48 mus_window_surface_ = | |
49 mus_window_->RequestSurface(mus::mojom::SurfaceType::DEFAULT); | |
50 } | |
51 | |
52 MusBrowserCompositorOutputSurface::~MusBrowserCompositorOutputSurface() {} | |
53 | |
54 void MusBrowserCompositorOutputSurface::SwapBuffers(cc::CompositorFrame frame) { | |
55 const gfx::Rect bounds(mus_window_->bounds().size()); | |
56 cc::CompositorFrame mus_frame; | |
57 mus_frame.metadata.device_scale_factor = 1.0f; | |
58 mus_frame.delegated_frame_data = base::MakeUnique<cc::DelegatedFrameData>(); | |
59 mus_frame.delegated_frame_data->resource_list.resize(0u); | |
60 const cc::RenderPassId render_pass_id(1, 1); | |
61 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); | |
62 const bool has_transparent_background = true; | |
63 pass->SetAll(render_pass_id, bounds, bounds, gfx::Transform(), | |
64 has_transparent_background); | |
65 // The SharedQuadState is owned by the SharedQuadStateList | |
66 // shared_quad_state_list. | |
67 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); | |
68 sqs->SetAll(gfx::Transform(), bounds.size(), bounds, bounds, | |
69 false /* is_clipped */, 1.f /* opacity */, SkXfermode::kSrc_Mode, | |
70 0 /* sorting_context_id */); | |
71 | |
72 cc::TransferableResource resource; | |
73 resource.id = AllocateResourceId(); | |
74 resource.format = cc::ResourceFormat::RGBA_8888; | |
75 resource.filter = GL_LINEAR; | |
76 resource.size = frame.gl_frame_data->size; | |
77 | |
78 const gpu::Mailbox& mailbox = GetMailboxFromResourceId(resource.id); | |
79 DCHECK(!mailbox.IsZero()); | |
80 const gfx::Rect rect(frame.gl_frame_data->size); | |
81 | |
82 // Call parent's SwapBuffers to generate the front buffer, and then send the | |
83 // front buffer to mus. | |
84 // TODO(penghuang): we should avoid extra copies here by sending frames to mus | |
85 // directly from renderer. | |
86 GpuBrowserCompositorOutputSurface::SwapBuffers(std::move(frame)); | |
87 GetCommandBufferProxy()->TakeFrontBuffer(mailbox); | |
Fady Samuel
2016/06/30 20:28:04
Question for my own edification: Does this mean we
Peng
2016/06/30 20:49:07
As my understanding, for the chrome offscreen chro
piman
2016/06/30 20:56:31
Yes, please, set it to false. The default is true
| |
88 | |
89 auto* gl = context_provider()->ContextGL(); | |
90 const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM(); | |
91 gl->ShallowFlushCHROMIUM(); | |
92 gpu::SyncToken sync_token; | |
93 gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); | |
94 | |
95 resource.mailbox_holder = | |
96 gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D); | |
97 resource.read_lock_fences_enabled = false; | |
98 resource.is_software = false; | |
99 resource.is_overlay_candidate = false; | |
100 mus_frame.delegated_frame_data->resource_list.push_back(std::move(resource)); | |
101 | |
102 const bool needs_blending = true; | |
103 const bool premultiplied_alpha = true; | |
104 const gfx::PointF uv_top_left(0.f, 0.f); | |
105 const gfx::PointF uv_bottom_right(1.f, 1.f); | |
106 const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; | |
107 const bool y_flipped = true; | |
108 const bool nearest_neighbor = false; | |
109 | |
110 cc::TextureDrawQuad* quad = | |
111 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); | |
112 const uint32_t transparent_color = 0x00000000; | |
113 quad->SetAll(sqs, rect, rect, rect, needs_blending, resource.id, gfx::Size(), | |
114 premultiplied_alpha, uv_top_left, uv_bottom_right, | |
115 transparent_color, vertex_opacity, y_flipped, nearest_neighbor, | |
116 false); | |
117 | |
118 mus_frame.delegated_frame_data->render_pass_list.push_back(std::move(pass)); | |
119 mus_window_surface_->SubmitCompositorFrame( | |
120 std::move(mus_frame), | |
121 base::Bind(&MusBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted, | |
122 base::Unretained(this), std::vector<ui::LatencyInfo>(), | |
123 gfx::SwapResult::SWAP_ACK, nullptr)); | |
124 return; | |
125 } | |
126 | |
127 bool MusBrowserCompositorOutputSurface::BindToClient( | |
128 cc::OutputSurfaceClient* client) { | |
129 if (!GpuBrowserCompositorOutputSurface::BindToClient(client)) | |
130 return false; | |
131 mus_window_surface_->BindToThread(); | |
132 mus_window_surface_->set_client(this); | |
133 return true; | |
134 } | |
135 | |
136 void MusBrowserCompositorOutputSurface::OnResourcesReturned( | |
137 mus::WindowSurface* surface, | |
138 mojo::Array<cc::ReturnedResource> resources) { | |
139 for (size_t i = 0; i < resources.size(); ++i) { | |
140 cc::ReturnedResource resource = std::move(resources[i]); | |
141 DCHECK_EQ(1, resource.count); | |
142 const gpu::Mailbox& mailbox = GetMailboxFromResourceId(resource.id); | |
143 GetCommandBufferProxy()->ReturnFrontBuffer(mailbox, resource.sync_token, | |
144 resource.lost); | |
145 FreeResourceId(resource.id); | |
146 } | |
147 } | |
148 | |
149 uint32_t MusBrowserCompositorOutputSurface::AllocateResourceId() { | |
150 if (!free_resource_ids_.empty()) { | |
151 uint32_t id = free_resource_ids_.back(); | |
152 free_resource_ids_.pop_back(); | |
153 return id; | |
154 } | |
155 // Generate a new mailbox. | |
156 uint32_t id = mailboxs_.size(); | |
157 mailboxs_.push_back(gpu::Mailbox::Generate()); | |
158 return id; | |
159 } | |
160 | |
161 void MusBrowserCompositorOutputSurface::FreeResourceId(uint32_t id) { | |
162 DCHECK_LT(id, mailboxs_.size()); | |
163 DCHECK(std::find(free_resource_ids_.begin(), free_resource_ids_.end(), id) == | |
164 free_resource_ids_.end()); | |
165 free_resource_ids_.push_back(id); | |
166 } | |
167 | |
168 const gpu::Mailbox& MusBrowserCompositorOutputSurface::GetMailboxFromResourceId( | |
169 uint32_t id) { | |
170 DCHECK_LT(id, mailboxs_.size()); | |
171 DCHECK(std::find(free_resource_ids_.begin(), free_resource_ids_.end(), id) == | |
172 free_resource_ids_.end()); | |
173 return mailboxs_[id]; | |
174 } | |
175 | |
176 } // namespace content | |
OLD | NEW |