Dismiss autofill popup on screen orientation change.
[chromium-blink-merge.git] / cc / output / delegating_renderer.cc
blobbe8ab031e9771f25f5af1def4f38b1dc6591d04f
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 OutputSurface* output_surface,
35 ResourceProvider* resource_provider) {
36 scoped_ptr<DelegatingRenderer> renderer(
37 new DelegatingRenderer(client, output_surface, resource_provider));
38 if (!renderer->Initialize())
39 return scoped_ptr<DelegatingRenderer>();
40 return renderer.Pass();
43 DelegatingRenderer::DelegatingRenderer(
44 RendererClient* client,
45 OutputSurface* output_surface,
46 ResourceProvider* resource_provider)
47 : Renderer(client),
48 output_surface_(output_surface),
49 resource_provider_(resource_provider),
50 visible_(true) {
51 DCHECK(resource_provider_);
54 bool DelegatingRenderer::Initialize() {
55 capabilities_.using_partial_swap = false;
56 capabilities_.max_texture_size = resource_provider_->max_texture_size();
57 capabilities_.best_texture_format = resource_provider_->best_texture_format();
58 capabilities_.allow_partial_texture_updates = false;
59 capabilities_.using_offscreen_context3d = false;
61 if (!output_surface_->context_provider()) {
62 // TODO(danakj): Make software compositing work.
63 return true;
66 WebGraphicsContext3D* context3d =
67 output_surface_->context_provider()->Context3d();
69 if (!context3d->makeContextCurrent())
70 return false;
72 std::string unique_context_name = base::StringPrintf(
73 "%s-%p",
74 Settings().compositor_name.c_str(),
75 context3d);
76 context3d->pushGroupMarkerEXT(unique_context_name.c_str());
78 std::string extensions_string =
79 UTF16ToASCII(context3d->getString(GL_EXTENSIONS));
81 std::vector<std::string> extensions;
82 base::SplitString(extensions_string, ' ', &extensions);
84 // TODO(danakj): We need non-GPU-specific paths for these things. This
85 // renderer shouldn't need to use context3d extensions directly.
86 bool has_set_visibility = false;
87 bool has_io_surface = false;
88 bool has_arb_texture_rect = false;
89 bool has_egl_image = false;
90 bool has_map_image = false;
91 for (size_t i = 0; i < extensions.size(); ++i) {
92 if (extensions[i] == "GL_CHROMIUM_set_visibility") {
93 has_set_visibility = true;
94 } else if (extensions[i] == "GL_CHROMIUM_iosurface") {
95 has_io_surface = true;
96 } else if (extensions[i] == "GL_ARB_texture_rectangle") {
97 has_arb_texture_rect = true;
98 } else if (extensions[i] == "GL_OES_EGL_image_external") {
99 has_egl_image = true;
100 } else if (extensions[i] == "GL_CHROMIUM_map_image") {
101 has_map_image = true;
105 if (has_io_surface)
106 DCHECK(has_arb_texture_rect);
108 capabilities_.using_set_visibility = has_set_visibility;
110 capabilities_.using_egl_image = has_egl_image;
112 capabilities_.using_map_image = has_map_image;
114 return true;
117 DelegatingRenderer::~DelegatingRenderer() {}
119 const RendererCapabilities& DelegatingRenderer::Capabilities() const {
120 return capabilities_;
123 bool DelegatingRenderer::CanReadPixels() const { return false; }
125 static ResourceProvider::ResourceId AppendToArray(
126 ResourceProvider::ResourceIdArray* array,
127 ResourceProvider::ResourceId id) {
128 array->push_back(id);
129 return id;
132 void DelegatingRenderer::DrawFrame(
133 RenderPassList* render_passes_in_draw_order) {
134 TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");
136 DCHECK(!frame_for_swap_buffers_.delegated_frame_data);
138 frame_for_swap_buffers_.metadata = client_->MakeCompositorFrameMetadata();
140 frame_for_swap_buffers_.delegated_frame_data =
141 make_scoped_ptr(new DelegatedFrameData);
142 DelegatedFrameData& out_data = *frame_for_swap_buffers_.delegated_frame_data;
143 // Move the render passes and resources into the |out_frame|.
144 out_data.render_pass_list.swap(*render_passes_in_draw_order);
146 // Collect all resource ids in the render passes into a ResourceIdArray.
147 ResourceProvider::ResourceIdArray resources;
148 DrawQuad::ResourceIteratorCallback append_to_array =
149 base::Bind(&AppendToArray, &resources);
150 for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) {
151 RenderPass* render_pass = out_data.render_pass_list.at(i);
152 for (size_t j = 0; j < render_pass->quad_list.size(); ++j)
153 render_pass->quad_list[j]->IterateResources(append_to_array);
155 resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
158 void DelegatingRenderer::SwapBuffers() {
159 TRACE_EVENT0("cc", "DelegatingRenderer::SwapBuffers");
161 output_surface_->SwapBuffers(&frame_for_swap_buffers_);
162 frame_for_swap_buffers_.delegated_frame_data.reset();
165 void DelegatingRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) {
166 NOTREACHED();
169 void DelegatingRenderer::ReceiveSwapBuffersAck(
170 const CompositorFrameAck& ack) {
171 resource_provider_->ReceiveFromParent(ack.resources);
174 bool DelegatingRenderer::IsContextLost() {
175 ContextProvider* context_provider = output_surface_->context_provider();
176 if (!context_provider)
177 return false;
178 return context_provider->Context3d()->getGraphicsResetStatusARB() !=
179 GL_NO_ERROR;
182 void DelegatingRenderer::SetVisible(bool visible) {
183 if (visible == visible_)
184 return;
186 visible_ = visible;
187 ContextProvider* context_provider = output_surface_->context_provider();
188 if (!visible_) {
189 TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
190 resource_provider_->ReleaseCachedData();
191 if (context_provider)
192 context_provider->Context3d()->flush();
194 if (capabilities_.using_set_visibility) {
195 // We loop visibility to the GPU process, since that's what manages memory.
196 // That will allow it to feed us with memory allocations that we can act
197 // upon.
198 DCHECK(context_provider);
199 context_provider->Context3d()->setVisibilityCHROMIUM(visible);
203 void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible,
204 size_t bytes_visible_and_nearby,
205 size_t bytes_allocated) {
206 ContextProvider* context_provider = output_surface_->context_provider();
207 if (!context_provider) {
208 // TODO(piman): software path.
209 NOTIMPLEMENTED();
210 return;
212 WebKit::WebGraphicsManagedMemoryStats stats;
213 stats.bytesVisible = bytes_visible;
214 stats.bytesVisibleAndNearby = bytes_visible_and_nearby;
215 stats.bytesAllocated = bytes_allocated;
216 stats.backbufferRequested = false;
217 context_provider->Context3d()->sendManagedMemoryStatsCHROMIUM(&stats);
220 void DelegatingRenderer::SetDiscardBackBufferWhenNotVisible(bool discard) {
221 // Nothing to do, we don't have a back buffer.
224 } // namespace cc