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