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