Change message loop to UI.
[chromium-blink-merge.git] / cc / output / delegating_renderer.cc
blob772a16ac657bee36f57df0eb71ec2f6ce97ff4c0
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"
7 #include <set>
8 #include <string>
9 #include <vector>
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 "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
26 #include "third_party/khronos/GLES2/gl2ext.h"
28 using WebKit::WebGraphicsContext3D;
30 namespace cc {
32 scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create(
33 RendererClient* client,
34 const LayerTreeSettings* settings,
35 OutputSurface* output_surface,
36 ResourceProvider* resource_provider) {
37 scoped_ptr<DelegatingRenderer> renderer(new DelegatingRenderer(
38 client, settings, output_surface, resource_provider));
39 if (!renderer->Initialize())
40 return scoped_ptr<DelegatingRenderer>();
41 return renderer.Pass();
44 DelegatingRenderer::DelegatingRenderer(RendererClient* client,
45 const LayerTreeSettings* settings,
46 OutputSurface* output_surface,
47 ResourceProvider* resource_provider)
48 : Renderer(client, settings),
49 output_surface_(output_surface),
50 resource_provider_(resource_provider),
51 visible_(true) {
52 DCHECK(resource_provider_);
55 bool DelegatingRenderer::Initialize() {
56 capabilities_.using_partial_swap = false;
57 capabilities_.max_texture_size = resource_provider_->max_texture_size();
58 capabilities_.best_texture_format = resource_provider_->best_texture_format();
59 capabilities_.allow_partial_texture_updates = false;
60 capabilities_.using_offscreen_context3d = false;
62 if (!output_surface_->context_provider()) {
63 // TODO(danakj): Make software compositing work.
64 return true;
67 WebGraphicsContext3D* context3d =
68 output_surface_->context_provider()->Context3d();
70 if (!context3d->makeContextCurrent())
71 return false;
73 const ContextProvider::Capabilities& caps =
74 output_surface_->context_provider()->ContextCapabilities();
76 DCHECK(!caps.iosurface || caps.texture_rectangle);
78 capabilities_.using_set_visibility = caps.set_visibility;
79 capabilities_.using_egl_image = caps.egl_image_external;
80 capabilities_.using_map_image = settings_->use_map_image && caps.map_image;
82 return true;
85 DelegatingRenderer::~DelegatingRenderer() {}
87 const RendererCapabilities& DelegatingRenderer::Capabilities() const {
88 return capabilities_;
91 bool DelegatingRenderer::CanReadPixels() const { return false; }
93 static ResourceProvider::ResourceId AppendToArray(
94 ResourceProvider::ResourceIdArray* array,
95 ResourceProvider::ResourceId id) {
96 array->push_back(id);
97 return id;
100 void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
101 ContextProvider* offscreen_context_provider,
102 float device_scale_factor,
103 bool allow_partial_swap,
104 bool disable_picture_quad_image_filtering) {
105 TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");
107 DCHECK(!frame_for_swap_buffers_.delegated_frame_data);
109 frame_for_swap_buffers_.metadata = client_->MakeCompositorFrameMetadata();
111 frame_for_swap_buffers_.delegated_frame_data =
112 make_scoped_ptr(new DelegatedFrameData);
113 DelegatedFrameData& out_data = *frame_for_swap_buffers_.delegated_frame_data;
114 // Move the render passes and resources into the |out_frame|.
115 out_data.render_pass_list.swap(*render_passes_in_draw_order);
117 // Collect all resource ids in the render passes into a ResourceIdArray.
118 ResourceProvider::ResourceIdArray resources;
119 DrawQuad::ResourceIteratorCallback append_to_array =
120 base::Bind(&AppendToArray, &resources);
121 for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) {
122 RenderPass* render_pass = out_data.render_pass_list.at(i);
123 for (size_t j = 0; j < render_pass->quad_list.size(); ++j)
124 render_pass->quad_list[j]->IterateResources(append_to_array);
126 resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
129 void DelegatingRenderer::SwapBuffers() {
130 TRACE_EVENT0("cc", "DelegatingRenderer::SwapBuffers");
132 output_surface_->SwapBuffers(&frame_for_swap_buffers_);
133 frame_for_swap_buffers_.delegated_frame_data.reset();
136 void DelegatingRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
137 NOTREACHED();
140 void DelegatingRenderer::ReceiveSwapBuffersAck(
141 const CompositorFrameAck& ack) {
142 resource_provider_->ReceiveReturnsFromParent(ack.resources);
145 bool DelegatingRenderer::IsContextLost() {
146 ContextProvider* context_provider = output_surface_->context_provider();
147 if (!context_provider)
148 return false;
149 return context_provider->Context3d()->getGraphicsResetStatusARB() !=
150 GL_NO_ERROR;
153 void DelegatingRenderer::SetVisible(bool visible) {
154 if (visible == visible_)
155 return;
157 visible_ = visible;
158 ContextProvider* context_provider = output_surface_->context_provider();
159 if (!visible_) {
160 TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
161 resource_provider_->ReleaseCachedData();
162 if (context_provider)
163 context_provider->Context3d()->flush();
165 if (capabilities_.using_set_visibility) {
166 // We loop visibility to the GPU process, since that's what manages memory.
167 // That will allow it to feed us with memory allocations that we can act
168 // upon.
169 DCHECK(context_provider);
170 context_provider->Context3d()->setVisibilityCHROMIUM(visible);
174 void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible,
175 size_t bytes_visible_and_nearby,
176 size_t bytes_allocated) {
177 ContextProvider* context_provider = output_surface_->context_provider();
178 if (!context_provider) {
179 // TODO(piman): software path.
180 NOTIMPLEMENTED();
181 return;
183 WebKit::WebGraphicsManagedMemoryStats stats;
184 stats.bytesVisible = bytes_visible;
185 stats.bytesVisibleAndNearby = bytes_visible_and_nearby;
186 stats.bytesAllocated = bytes_allocated;
187 stats.backbufferRequested = false;
188 context_provider->Context3d()->sendManagedMemoryStatsCHROMIUM(&stats);
191 void DelegatingRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) {
192 // Nothing to do, we don't have a back buffer.
195 } // namespace cc