1 // Copyright 2012 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/delegating_renderer.h"
11 #include "base/debug/trace_event.h"
12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "cc/output/compositor_frame_ack.h"
16 #include "cc/quads/checkerboard_draw_quad.h"
17 #include "cc/quads/debug_border_draw_quad.h"
18 #include "cc/quads/render_pass.h"
19 #include "cc/quads/render_pass_draw_quad.h"
20 #include "cc/quads/solid_color_draw_quad.h"
21 #include "cc/quads/texture_draw_quad.h"
22 #include "cc/quads/tile_draw_quad.h"
23 #include "cc/quads/yuv_video_draw_quad.h"
24 #include "cc/resources/resource_provider.h"
25 #include "gpu/command_buffer/client/context_support.h"
26 #include "gpu/command_buffer/client/gles2_interface.h"
27 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
28 #include "third_party/khronos/GLES2/gl2ext.h"
33 scoped_ptr
<DelegatingRenderer
> DelegatingRenderer::Create(
34 RendererClient
* client
,
35 const LayerTreeSettings
* settings
,
36 OutputSurface
* output_surface
,
37 ResourceProvider
* resource_provider
) {
38 scoped_ptr
<DelegatingRenderer
> renderer(new DelegatingRenderer(
39 client
, settings
, output_surface
, resource_provider
));
40 if (!renderer
->Initialize())
41 return scoped_ptr
<DelegatingRenderer
>();
42 return renderer
.Pass();
45 DelegatingRenderer::DelegatingRenderer(RendererClient
* client
,
46 const LayerTreeSettings
* settings
,
47 OutputSurface
* output_surface
,
48 ResourceProvider
* resource_provider
)
49 : Renderer(client
, settings
),
50 output_surface_(output_surface
),
51 resource_provider_(resource_provider
),
53 DCHECK(resource_provider_
);
56 bool DelegatingRenderer::Initialize() {
57 capabilities_
.using_partial_swap
= false;
58 capabilities_
.max_texture_size
= resource_provider_
->max_texture_size();
59 capabilities_
.best_texture_format
= resource_provider_
->best_texture_format();
60 capabilities_
.allow_partial_texture_updates
= false;
61 capabilities_
.using_offscreen_context3d
= false;
63 if (!output_surface_
->context_provider()) {
64 capabilities_
.using_shared_memory_resources
= true;
65 capabilities_
.using_map_image
= settings_
->use_map_image
;
69 const ContextProvider::Capabilities
& caps
=
70 output_surface_
->context_provider()->ContextCapabilities();
72 DCHECK(!caps
.gpu
.iosurface
|| caps
.gpu
.texture_rectangle
);
74 capabilities_
.using_egl_image
= caps
.gpu
.egl_image_external
;
75 capabilities_
.using_map_image
=
76 settings_
->use_map_image
&& caps
.gpu
.map_image
;
78 capabilities_
.allow_rasterize_on_demand
= false;
83 DelegatingRenderer::~DelegatingRenderer() {}
85 const RendererCapabilitiesImpl
& DelegatingRenderer::Capabilities() const {
89 bool DelegatingRenderer::CanReadPixels() const { return false; }
91 static ResourceProvider::ResourceId
AppendToArray(
92 ResourceProvider::ResourceIdArray
* array
,
93 ResourceProvider::ResourceId id
) {
98 void DelegatingRenderer::DrawFrame(RenderPassList
* render_passes_in_draw_order
,
99 ContextProvider
* offscreen_context_provider
,
100 float device_scale_factor
,
101 const gfx::Rect
& device_viewport_rect
,
102 const gfx::Rect
& device_clip_rect
,
103 bool disable_picture_quad_image_filtering
) {
104 TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");
106 DCHECK(!delegated_frame_data_
);
108 delegated_frame_data_
= make_scoped_ptr(new DelegatedFrameData
);
109 DelegatedFrameData
& out_data
= *delegated_frame_data_
;
110 // Move the render passes and resources into the |out_frame|.
111 out_data
.render_pass_list
.swap(*render_passes_in_draw_order
);
113 // Collect all resource ids in the render passes into a ResourceIdArray.
114 ResourceProvider::ResourceIdArray resources
;
115 DrawQuad::ResourceIteratorCallback append_to_array
=
116 base::Bind(&AppendToArray
, &resources
);
117 for (size_t i
= 0; i
< out_data
.render_pass_list
.size(); ++i
) {
118 RenderPass
* render_pass
= out_data
.render_pass_list
.at(i
);
119 for (size_t j
= 0; j
< render_pass
->quad_list
.size(); ++j
)
120 render_pass
->quad_list
[j
]->IterateResources(append_to_array
);
122 resource_provider_
->PrepareSendToParent(resources
, &out_data
.resource_list
);
125 void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata
& metadata
) {
126 TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers");
127 CompositorFrame compositor_frame
;
128 compositor_frame
.metadata
= metadata
;
129 compositor_frame
.delegated_frame_data
= delegated_frame_data_
.Pass();
130 output_surface_
->SwapBuffers(&compositor_frame
);
133 void DelegatingRenderer::GetFramebufferPixels(void* pixels
,
134 const gfx::Rect
& rect
) {
138 void DelegatingRenderer::ReceiveSwapBuffersAck(
139 const CompositorFrameAck
& ack
) {
140 resource_provider_
->ReceiveReturnsFromParent(ack
.resources
);
143 bool DelegatingRenderer::IsContextLost() {
144 ContextProvider
* context_provider
= output_surface_
->context_provider();
145 if (!context_provider
)
147 return context_provider
->IsContextLost();
150 void DelegatingRenderer::SetVisible(bool visible
) {
151 if (visible
== visible_
)
155 ContextProvider
* context_provider
= output_surface_
->context_provider();
157 TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
158 resource_provider_
->ReleaseCachedData();
159 if (context_provider
)
160 context_provider
->ContextGL()->Flush();
162 // We loop visibility to the GPU process, since that's what manages memory.
163 // That will allow it to feed us with memory allocations that we can act
165 if (context_provider
)
166 context_provider
->ContextSupport()->SetSurfaceVisible(visible
);
169 void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible
,
170 size_t bytes_visible_and_nearby
,
171 size_t bytes_allocated
) {
172 ContextProvider
* context_provider
= output_surface_
->context_provider();
173 if (!context_provider
) {
174 // In the software path each child process manages its memory separately,
175 // so memory stats don't have to be sent anywhere.
178 gpu::ManagedMemoryStats stats
;
179 stats
.bytes_required
= bytes_visible
;
180 stats
.bytes_nice_to_have
= bytes_visible_and_nearby
;
181 stats
.bytes_allocated
= bytes_allocated
;
182 stats
.backbuffer_requested
= false;
184 context_provider
->ContextSupport()->SendManagedMemoryStats(stats
);