1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/surfaces/display.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/debug/trace_event.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/message_loop/message_loop.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/output/compositor_frame.h" 10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "cc/output/compositor_frame_ack.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/output/direct_renderer.h" 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/output/gl_renderer.h" 13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "cc/output/software_renderer.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/surfaces/display_client.h" 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/surfaces/surface.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "cc/surfaces/surface_aggregator.h" 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "cc/surfaces/surface_manager.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/trees/blocking_task_runner.h" 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace cc { 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)Display::Display(DisplayClient* client, 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SurfaceManager* manager, 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) SharedBitmapManager* bitmap_manager) 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : client_(client), 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci manager_(manager), 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bitmap_manager_(bitmap_manager), 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blocking_main_thread_task_runner_( 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BlockingTaskRunner::Create(base::MessageLoopProxy::current())) { 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->AddObserver(this); 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)Display::~Display() { 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) manager_->RemoveObserver(this); 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid Display::Resize(SurfaceId id, const gfx::Size& size) { 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_surface_id_ = id; 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch current_surface_size_ = size; 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) client_->DisplayDamaged(); 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void Display::InitializeOutputSurface() { 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (output_surface_) 45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<OutputSurface> output_surface = client_->CreateOutputSurface(); 47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!output_surface->BindToClient(this)) 48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int highp_threshold_min = 0; 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool use_rgba_4444_texture_format = false; 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t id_allocation_chunk_size = 1; 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool use_distance_field_text = false; 54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<ResourceProvider> resource_provider = 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ResourceProvider::Create(output_surface.get(), 56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bitmap_manager_, 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci blocking_main_thread_task_runner_.get(), 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) highp_threshold_min, 59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) use_rgba_4444_texture_format, 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) id_allocation_chunk_size, 61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) use_distance_field_text); 62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!resource_provider) 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (output_surface->context_provider()) { 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) TextureMailboxDeleter* texture_mailbox_deleter = NULL; 67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<GLRenderer> renderer = 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GLRenderer::Create(this, 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) &settings_, 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) output_surface.get(), 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resource_provider.get(), 72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) texture_mailbox_deleter, 73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) highp_threshold_min); 74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!renderer) 75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) renderer_ = renderer.Pass(); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else { 78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create( 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, &settings_, output_surface.get(), resource_provider.get()); 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!renderer) 81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) renderer_ = renderer.Pass(); 83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) output_surface_ = output_surface.Pass(); 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) resource_provider_ = resource_provider.Pass(); 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get())); 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool Display::Draw() { 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (current_surface_id_.is_null()) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) InitializeOutputSurface(); 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!output_surface_) 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // while Aggregate is called to immediately run release callbacks afterward. 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<CompositorFrame> frame = 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci aggregator_->Aggregate(current_surface_id_); 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!frame) 103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch TRACE_EVENT0("cc", "Display::Draw"); 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DelegatedFrameData* frame_data = frame->delegated_frame_data.get(); 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Only reshape when we know we are going to draw. Otherwise, the reshape 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // can leave the window at the wrong size if we never draw and the proper 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // viewport size is never set. 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch output_surface_->Reshape(current_surface_size_, 1.f); 112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) float device_scale_factor = 1.0f; 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_); 114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Rect device_clip_rect = device_viewport_rect; 115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool disable_picture_quad_image_filtering = false; 116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch renderer_->DecideRenderPassAllocationsForFrame(frame_data->render_pass_list); 118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) renderer_->DrawFrame(&frame_data->render_pass_list, 119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) device_scale_factor, 120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) device_viewport_rect, 121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) device_clip_rect, 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) disable_picture_quad_image_filtering); 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci renderer_->SwapBuffers(frame->metadata); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (SurfaceAggregator::SurfaceIndexMap::iterator it = 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci aggregator_->previous_contained_surfaces().begin(); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != aggregator_->previous_contained_surfaces().end(); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it) { 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Surface* surface = manager_->GetSurfaceForId(it->first); 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (surface) 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci surface->RunDrawCallbacks(); 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Display::DidSwapBuffers() { 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->DidSwapBuffers(); 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Display::DidSwapBuffersComplete() { 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->DidSwapBuffersComplete(); 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Display::CommitVSyncParameters(base::TimeTicks timebase, 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta interval) { 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci client_->CommitVSyncParameters(timebase, interval); 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void Display::OnSurfaceDamaged(SurfaceId surface) { 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface)) 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) client_->DisplayDamaged(); 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)SurfaceId Display::CurrentSurfaceId() { 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return current_surface_id_; 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint Display::GetMaxFramesPending() { 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!output_surface_) 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return OutputSurface::DEFAULT_MAX_FRAMES_PENDING; 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return output_surface_->capabilities().max_frames_pending; 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace cc 164