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/client/gles2_interface.h" 27 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 28 #include "third_party/khronos/GLES2/gl2ext.h" 29 30 31 namespace cc { 32 33 scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create( 34 RendererClient* client, 35 const LayerTreeSettings* settings, 36 OutputSurface* output_surface, 37 ResourceProvider* resource_provider) { 38 return make_scoped_ptr(new DelegatingRenderer( 39 client, settings, output_surface, resource_provider)); 40 } 41 42 DelegatingRenderer::DelegatingRenderer(RendererClient* client, 43 const LayerTreeSettings* settings, 44 OutputSurface* output_surface, 45 ResourceProvider* resource_provider) 46 : Renderer(client, settings), 47 output_surface_(output_surface), 48 resource_provider_(resource_provider) { 49 DCHECK(resource_provider_); 50 51 capabilities_.using_partial_swap = false; 52 capabilities_.max_texture_size = resource_provider_->max_texture_size(); 53 capabilities_.best_texture_format = resource_provider_->best_texture_format(); 54 capabilities_.allow_partial_texture_updates = false; 55 56 if (!output_surface_->context_provider()) { 57 capabilities_.using_shared_memory_resources = true; 58 capabilities_.using_map_image = true; 59 } else { 60 const ContextProvider::Capabilities& caps = 61 output_surface_->context_provider()->ContextCapabilities(); 62 63 DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle); 64 65 capabilities_.using_egl_image = caps.gpu.egl_image_external; 66 capabilities_.using_map_image = caps.gpu.map_image; 67 68 capabilities_.allow_rasterize_on_demand = false; 69 } 70 } 71 72 DelegatingRenderer::~DelegatingRenderer() {} 73 74 const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const { 75 return capabilities_; 76 } 77 78 static ResourceProvider::ResourceId AppendToArray( 79 ResourceProvider::ResourceIdArray* array, 80 ResourceProvider::ResourceId id) { 81 array->push_back(id); 82 return id; 83 } 84 85 void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, 86 float device_scale_factor, 87 const gfx::Rect& device_viewport_rect, 88 const gfx::Rect& device_clip_rect, 89 bool disable_picture_quad_image_filtering) { 90 TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame"); 91 92 DCHECK(!delegated_frame_data_); 93 94 delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData); 95 DelegatedFrameData& out_data = *delegated_frame_data_; 96 out_data.device_scale_factor = device_scale_factor; 97 // Move the render passes and resources into the |out_frame|. 98 out_data.render_pass_list.swap(*render_passes_in_draw_order); 99 100 // Collect all resource ids in the render passes into a ResourceIdArray. 101 ResourceProvider::ResourceIdArray resources; 102 DrawQuad::ResourceIteratorCallback append_to_array = 103 base::Bind(&AppendToArray, &resources); 104 for (size_t i = 0; i < out_data.render_pass_list.size(); ++i) { 105 RenderPass* render_pass = out_data.render_pass_list.at(i); 106 for (size_t j = 0; j < render_pass->quad_list.size(); ++j) 107 render_pass->quad_list[j]->IterateResources(append_to_array); 108 } 109 resource_provider_->PrepareSendToParent(resources, &out_data.resource_list); 110 } 111 112 void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { 113 TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers"); 114 CompositorFrame compositor_frame; 115 compositor_frame.metadata = metadata; 116 compositor_frame.delegated_frame_data = delegated_frame_data_.Pass(); 117 output_surface_->SwapBuffers(&compositor_frame); 118 } 119 120 void DelegatingRenderer::ReceiveSwapBuffersAck( 121 const CompositorFrameAck& ack) { 122 resource_provider_->ReceiveReturnsFromParent(ack.resources); 123 } 124 125 bool DelegatingRenderer::IsContextLost() { 126 ContextProvider* context_provider = output_surface_->context_provider(); 127 if (!context_provider) 128 return false; 129 return context_provider->IsContextLost(); 130 } 131 132 void DelegatingRenderer::DidChangeVisibility() { 133 ContextProvider* context_provider = output_surface_->context_provider(); 134 if (!visible()) { 135 TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources"); 136 resource_provider_->ReleaseCachedData(); 137 if (context_provider) { 138 context_provider->DeleteCachedResources(); 139 context_provider->ContextGL()->Flush(); 140 } 141 } 142 // We loop visibility to the GPU process, since that's what manages memory. 143 // That will allow it to feed us with memory allocations that we can act 144 // upon. 145 if (context_provider) 146 context_provider->ContextSupport()->SetSurfaceVisible(visible()); 147 } 148 149 } // namespace cc 150