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 "cc/output/compositor_frame.h" | |
10 #include "cc/quads/render_pass.h" | |
11 #include "cc/quads/texture_draw_quad.h" | |
12 #include "components/display_compositor/compositor_overlay_candidate_validator.h " | |
13 #include "content/common/gpu/client/context_provider_command_buffer.h" | |
Fady Samuel
2016/07/06 14:44:19
Is this moving out of content?
Peng
2016/07/06 15:10:03
They cannot go to //gpu/ipc. Maybe they need a new
| |
14 #include "gpu/command_buffer/client/gles2_interface.h" | |
15 #include "gpu/ipc/client/command_buffer_proxy_impl.h" | |
16 #include "services/ui/common/gpu_service.h" | |
17 #include "services/ui/public/cpp/window.h" | |
18 #include "services/ui/public/cpp/window_surface.h" | |
19 #include "ui/views/mus/native_widget_mus.h" | |
20 #include "ui/views/mus/window_tree_host_mus.h" | |
21 | |
22 namespace content { | |
23 | |
24 MusBrowserCompositorOutputSurface::MusBrowserCompositorOutputSurface( | |
Fady Samuel
2016/07/06 14:44:19
We are moving away from the name Mus it seems. I a
Peng
2016/07/06 15:10:03
This class inherit from GpuBrowserCompositorOutput
| |
25 gpu::SurfaceHandle surface_handle, | |
26 scoped_refptr<ContextProviderCommandBuffer> context, | |
27 scoped_refptr<ui::CompositorVSyncManager> vsync_manager, | |
28 cc::SyntheticBeginFrameSource* begin_frame_source, | |
29 std::unique_ptr<display_compositor::CompositorOverlayCandidateValidator> | |
30 overlay_candidate_validator) | |
31 : GpuBrowserCompositorOutputSurface(std::move(context), | |
32 std::move(vsync_manager), | |
33 begin_frame_source, | |
34 std::move(overlay_candidate_validator)), | |
35 ui_window_(nullptr) { | |
36 DCHECK(ui::GpuService::UseChromeGpuCommandBuffer()); | |
37 views::WindowTreeHostMus* window_tree_host = | |
38 static_cast<views::WindowTreeHostMus*>( | |
39 aura::WindowTreeHost::GetForAcceleratedWidget(surface_handle)); | |
40 ui_window_ = window_tree_host->native_widget()->window(); | |
41 ui_window_surface_ = | |
42 ui_window_->RequestSurface(ui::mojom::SurfaceType::DEFAULT); | |
43 } | |
44 | |
45 MusBrowserCompositorOutputSurface::~MusBrowserCompositorOutputSurface() {} | |
46 | |
47 void MusBrowserCompositorOutputSurface::SwapBuffers(cc::CompositorFrame frame) { | |
48 const gfx::Rect bounds(ui_window_->bounds().size()); | |
49 cc::CompositorFrame ui_frame; | |
50 ui_frame.metadata.device_scale_factor = 1.0f; | |
piman
2016/07/07 21:02:20
Should you get the metadata from |frame| ?
Peng
2016/07/07 21:33:37
Done.
piman
2016/07/07 21:55:20
I meant, get the entire metadata, including latenc
Peng
2016/07/07 22:46:50
Done.
| |
51 ui_frame.delegated_frame_data = base::MakeUnique<cc::DelegatedFrameData>(); | |
52 const cc::RenderPassId render_pass_id(1, 1); | |
53 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create(); | |
54 const bool has_transparent_background = true; | |
55 pass->SetAll(render_pass_id, bounds, bounds, gfx::Transform(), | |
56 has_transparent_background); | |
57 // The SharedQuadState is owned by the SharedQuadStateList | |
58 // shared_quad_state_list. | |
59 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); | |
60 sqs->SetAll(gfx::Transform(), bounds.size(), bounds, bounds, | |
61 false /* is_clipped */, 1.f /* opacity */, SkXfermode::kSrc_Mode, | |
62 0 /* sorting_context_id */); | |
63 | |
64 cc::TransferableResource resource; | |
65 resource.id = AllocateResourceId(); | |
66 resource.format = cc::ResourceFormat::RGBA_8888; | |
67 resource.filter = GL_LINEAR; | |
68 resource.size = frame.gl_frame_data->size; | |
69 | |
70 const gpu::Mailbox& mailbox = GetMailboxFromResourceId(resource.id); | |
71 DCHECK(!mailbox.IsZero()); | |
72 const gfx::Rect rect(frame.gl_frame_data->size); | |
73 | |
74 // Call parent's SwapBuffers to generate the front buffer, and then send the | |
75 // front buffer to mus. | |
76 // TODO(penghuang): we should avoid extra copies here by sending frames to mus | |
77 // directly from renderer. | |
78 GpuBrowserCompositorOutputSurface::SwapBuffers(std::move(frame)); | |
79 GetCommandBufferProxy()->TakeFrontBuffer(mailbox); | |
80 | |
81 auto* gl = context_provider()->ContextGL(); | |
82 const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM(); | |
83 gl->ShallowFlushCHROMIUM(); | |
84 gpu::SyncToken sync_token; | |
85 gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); | |
86 | |
87 resource.mailbox_holder = | |
88 gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D); | |
89 resource.read_lock_fences_enabled = false; | |
90 resource.is_software = false; | |
91 resource.is_overlay_candidate = false; | |
92 ui_frame.delegated_frame_data->resource_list.push_back(std::move(resource)); | |
93 | |
94 const bool needs_blending = true; | |
95 const bool premultiplied_alpha = true; | |
96 const gfx::PointF uv_top_left(0.f, 0.f); | |
97 const gfx::PointF uv_bottom_right(1.f, 1.f); | |
98 const uint32_t background_color = 0x00000000; | |
99 const float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f}; | |
100 const bool y_flipped = true; | |
101 const bool nearest_neighbor = false; | |
102 const bool secure_output_only = false; | |
103 | |
104 cc::TextureDrawQuad* quad = | |
105 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>(); | |
106 quad->SetAll(sqs, rect, rect, rect, needs_blending, resource.id, gfx::Size(), | |
107 premultiplied_alpha, uv_top_left, uv_bottom_right, | |
108 background_color, vertex_opacity, y_flipped, nearest_neighbor, | |
109 secure_output_only); | |
110 | |
111 ui_frame.delegated_frame_data->render_pass_list.push_back(std::move(pass)); | |
112 ui_window_surface_->SubmitCompositorFrame( | |
113 std::move(ui_frame), | |
114 base::Bind(&MusBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted, | |
115 base::Unretained(this), std::vector<ui::LatencyInfo>(), | |
piman
2016/07/07 21:02:20
What makes Unretained safe?
Peng
2016/07/07 21:33:37
ui_window_surface_ will be destroyed with MusBrows
danakj
2016/07/07 21:42:45
That should go in a comment.
Peng
2016/07/07 22:46:50
Done.
| |
116 gfx::SwapResult::SWAP_ACK, nullptr)); | |
117 return; | |
118 } | |
119 | |
120 bool MusBrowserCompositorOutputSurface::BindToClient( | |
121 cc::OutputSurfaceClient* client) { | |
122 if (!GpuBrowserCompositorOutputSurface::BindToClient(client)) | |
123 return false; | |
124 ui_window_surface_->BindToThread(); | |
125 ui_window_surface_->set_client(this); | |
126 return true; | |
127 } | |
128 | |
129 void MusBrowserCompositorOutputSurface::OnResourcesReturned( | |
130 ui::WindowSurface* surface, | |
131 mojo::Array<cc::ReturnedResource> resources) { | |
132 for (const auto& resource : resources) { | |
133 DCHECK_EQ(1, resource.count); | |
134 const gpu::Mailbox& mailbox = GetMailboxFromResourceId(resource.id); | |
135 GetCommandBufferProxy()->ReturnFrontBuffer(mailbox, resource.sync_token, | |
136 resource.lost); | |
137 FreeResourceId(resource.id); | |
138 } | |
139 } | |
140 | |
141 uint32_t MusBrowserCompositorOutputSurface::AllocateResourceId() { | |
142 if (!free_resource_ids_.empty()) { | |
143 uint32_t id = free_resource_ids_.back(); | |
144 free_resource_ids_.pop_back(); | |
145 return id; | |
146 } | |
147 // If there is no free resource id, we generate a new mailbox in the mailbox | |
148 // vector, and the index of the new mailbox is the new allocated resource id. | |
149 uint32_t id = mailboxes_.size(); | |
150 mailboxes_.push_back(gpu::Mailbox::Generate()); | |
151 return id; | |
152 } | |
153 | |
154 void MusBrowserCompositorOutputSurface::FreeResourceId(uint32_t id) { | |
155 DCHECK_LT(id, mailboxes_.size()); | |
156 DCHECK(std::find(free_resource_ids_.begin(), free_resource_ids_.end(), id) == | |
157 free_resource_ids_.end()); | |
158 free_resource_ids_.push_back(id); | |
159 } | |
160 | |
161 const gpu::Mailbox& MusBrowserCompositorOutputSurface::GetMailboxFromResourceId( | |
162 uint32_t id) { | |
163 DCHECK_LT(id, mailboxes_.size()); | |
164 DCHECK(std::find(free_resource_ids_.begin(), free_resource_ids_.end(), id) == | |
165 free_resource_ids_.end()); | |
166 return mailboxes_[id]; | |
167 } | |
168 | |
169 } // namespace content | |
OLD | NEW |