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. 4 5 #include "cc/output/delegating_renderer.h" 6 7 #include <set> 8 #include <string> 9 #include <vector> 10 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/common/gpu_memory_allocation.h" 27 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 28 #include "third_party/khronos/GLES2/gl2ext.h" 29 30 using blink::WebGraphicsContext3D; 31 32 namespace cc { 33 34 scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create( 35 RendererClient* client, 36 const LayerTreeSettings* settings, 37 OutputSurface* output_surface, 38 ResourceProvider* resource_provider) { 39 scoped_ptr<DelegatingRenderer> renderer(new DelegatingRenderer( 40 client, settings, output_surface, resource_provider)); 41 if (!renderer->Initialize()) 42 return scoped_ptr<DelegatingRenderer>(); 43 return renderer.Pass(); 44 } 45 46 DelegatingRenderer::DelegatingRenderer(RendererClient* client, 47 const LayerTreeSettings* settings, 48 OutputSurface* output_surface, 49 ResourceProvider* resource_provider) 50 : Renderer(client, settings), 51 output_surface_(output_surface), 52 resource_provider_(resource_provider), 53 visible_(true) { 54 DCHECK(resource_provider_); 55 } 56 57 bool DelegatingRenderer::Initialize() { 58 capabilities_.using_partial_swap = false; 59 capabilities_.max_texture_size = resource_provider_->max_texture_size(); 60 capabilities_.best_texture_format = resource_provider_->best_texture_format(); 61 capabilities_.allow_partial_texture_updates = false; 62 capabilities_.using_offscreen_context3d = false; 63 64 if (!output_surface_->context_provider()) { 65 capabilities_.using_shared_memory_resources = true; 66 capabilities_.using_map_image = settings_->use_map_image; 67 return true; 68 } 69 70 const ContextProvider::Capabilities& caps = 71 output_surface_->context_provider()->ContextCapabilities(); 72 73 DCHECK(!caps.iosurface || caps.texture_rectangle); 74 75 capabilities_.using_egl_image = caps.egl_image_external; 76 capabilities_.using_map_image = settings_->use_map_image && caps.map_image; 77 78 return true; 79 } 80 81 DelegatingRenderer::~DelegatingRenderer() {} 82 83 const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const { 84 return capabilities_; 85 } 86 87 bool DelegatingRenderer::CanReadPixels() const { return false; } 88 89 static ResourceProvider::ResourceId AppendToArray( 90 ResourceProvider::ResourceIdArray* array, 91 ResourceProvider::ResourceId id) { 92 array->push_back(id); 93 return id; 94 } 95 96 void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, 97 ContextProvider* offscreen_context_provider, 98 float device_scale_factor, 99 gfx::Rect device_viewport_rect, 100 gfx::Rect device_clip_rect, 101 bool allow_partial_swap, 102 bool disable_picture_quad_image_filtering) { 103 TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame"); 104 105 DCHECK(!delegated_frame_data_); 106 107 delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData); 108 DelegatedFrameData& out_data = *delegated_frame_data_; 109 // Move the render passes and resources into the |out_frame|. 110 out_data.render_pass_list.swap(*render_passes_in_draw_order); 111 112 // Collect all resource ids in the render passes into a ResourceIdArray. 113 ResourceProvider::ResourceIdArray resources; 114 DrawQuad::ResourceIteratorCallback append_to_array = 115 base::Bind(&AppendToArray, &resources); 116 for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) { 117 RenderPass* render_pass = out_data.render_pass_list.at(i); 118 for (size_t j = 0; j < render_pass->quad_list.size(); ++j) 119 render_pass->quad_list[j]->IterateResources(append_to_array); 120 } 121 resource_provider_->PrepareSendToParent(resources, &out_data.resource_list); 122 } 123 124 void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { 125 TRACE_EVENT0("cc", "DelegatingRenderer::SwapBuffers"); 126 CompositorFrame compositor_frame; 127 compositor_frame.metadata = metadata; 128 compositor_frame.delegated_frame_data = delegated_frame_data_.Pass(); 129 output_surface_->SwapBuffers(&compositor_frame); 130 } 131 132 void DelegatingRenderer::GetFramebufferPixels(void* pixels, gfx::Rect rect) { 133 NOTREACHED(); 134 } 135 136 void DelegatingRenderer::ReceiveSwapBuffersAck( 137 const CompositorFrameAck& ack) { 138 resource_provider_->ReceiveReturnsFromParent(ack.resources); 139 } 140 141 bool DelegatingRenderer::IsContextLost() { 142 ContextProvider* context_provider = output_surface_->context_provider(); 143 if (!context_provider) 144 return false; 145 return context_provider->IsContextLost(); 146 } 147 148 void DelegatingRenderer::SetVisible(bool visible) { 149 if (visible == visible_) 150 return; 151 152 visible_ = visible; 153 ContextProvider* context_provider = output_surface_->context_provider(); 154 if (!visible_) { 155 TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources"); 156 resource_provider_->ReleaseCachedData(); 157 if (context_provider) 158 context_provider->Context3d()->flush(); 159 } 160 // We loop visibility to the GPU process, since that's what manages memory. 161 // That will allow it to feed us with memory allocations that we can act 162 // upon. 163 DCHECK(context_provider); 164 context_provider->ContextSupport()->SetSurfaceVisible(visible); 165 } 166 167 void DelegatingRenderer::SendManagedMemoryStats(size_t bytes_visible, 168 size_t bytes_visible_and_nearby, 169 size_t bytes_allocated) { 170 ContextProvider* context_provider = output_surface_->context_provider(); 171 if (!context_provider) { 172 // TODO(piman): software path. 173 NOTIMPLEMENTED(); 174 return; 175 } 176 gpu::ManagedMemoryStats stats; 177 stats.bytes_required = bytes_visible; 178 stats.bytes_nice_to_have = bytes_visible_and_nearby; 179 stats.bytes_allocated = bytes_allocated; 180 stats.backbuffer_requested = false; 181 182 context_provider->ContextSupport()->SendManagedMemoryStats(stats); 183 } 184 185 } // namespace cc 186