Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(219)

Side by Side Diff: sky/compositor/layer_host.cc

Issue 756673004: Surfaces should acknowledge frame submissions (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sky/compositor/layer_host.h" 5 #include "sky/compositor/layer_host.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "mojo/converters/geometry/geometry_type_converters.h" 9 #include "mojo/converters/geometry/geometry_type_converters.h"
10 #include "mojo/gpu/gl_context.h" 10 #include "mojo/gpu/gl_context.h"
11 #include "mojo/services/public/cpp/surfaces/surfaces_utils.h" 11 #include "mojo/services/public/cpp/surfaces/surfaces_utils.h"
12 #include "mojo/skia/ganesh_context.h" 12 #include "mojo/skia/ganesh_context.h"
13 #include "sky/compositor/layer.h" 13 #include "sky/compositor/layer.h"
14 14
15 namespace sky { 15 namespace sky {
16 16
17 LayerHost::LayerHost(LayerHostClient* client) 17 LayerHost::LayerHost(LayerHostClient* client)
18 : client_(client), 18 : client_(client),
19 state_(kIdle), 19 state_(kWaitingForSurfaceService),
20 frame_requested_(false),
20 surface_holder_(this, client->GetShell()), 21 surface_holder_(this, client->GetShell()),
21 gl_context_(mojo::GLContext::Create(client->GetShell())), 22 gl_context_(mojo::GLContext::Create(client->GetShell())),
22 ganesh_context_(gl_context_), 23 ganesh_context_(gl_context_),
23 resource_manager_(gl_context_), 24 resource_manager_(gl_context_),
24 scheduler_(this, base::MessageLoop::current()->task_runner()) { 25 weak_factory_(this) {
25 scheduler_.UpdateVSync(
26 TimeInterval(base::TimeTicks(), base::TimeDelta::FromSecondsD(1.0 / 60)));
27 } 26 }
28 27
29 LayerHost::~LayerHost() { 28 LayerHost::~LayerHost() {
30 } 29 }
31 30
32 void LayerHost::SetNeedsAnimate() { 31 void LayerHost::SetNeedsAnimate() {
33 scheduler_.SetNeedsFrame(); 32 if (frame_requested_)
34 state_ = kWaitingForBeginFrame; 33 return;
34 frame_requested_ = true;
35 if (state_ == kReadyForFrame)
36 BeginFrameSoon();
35 } 37 }
36 38
37 void LayerHost::SetRootLayer(scoped_refptr<Layer> layer) { 39 void LayerHost::SetRootLayer(scoped_refptr<Layer> layer) {
38 DCHECK(!root_layer_.get()); 40 DCHECK(!root_layer_.get());
39 root_layer_ = layer; 41 root_layer_ = layer;
40 root_layer_->set_host(this); 42 root_layer_->set_host(this);
41 } 43 }
42 44
45 void LayerHost::OnSurfaceConnectionCreated() {
46 DCHECK_EQ(state_, kWaitingForSurfaceService);
47 state_ = kReadyForFrame;
48 if (frame_requested_)
49 BeginFrameSoon();
50 }
51
43 void LayerHost::OnSurfaceIdAvailable(mojo::SurfaceIdPtr surface_id) { 52 void LayerHost::OnSurfaceIdAvailable(mojo::SurfaceIdPtr surface_id) {
44 client_->OnSurfaceIdAvailable(surface_id.Pass()); 53 client_->OnSurfaceIdAvailable(surface_id.Pass());
45
46 if (state_ == kWaitingForSurfaceToUploadFrame)
47 Upload(root_layer_.get());
48 } 54 }
49 55
50 void LayerHost::ReturnResources( 56 void LayerHost::ReturnResources(
51 mojo::Array<mojo::ReturnedResourcePtr> resources) { 57 mojo::Array<mojo::ReturnedResourcePtr> resources) {
52 resource_manager_.ReturnResources(resources.Pass()); 58 resource_manager_.ReturnResources(resources.Pass());
53 } 59 }
54 60
55 void LayerHost::BeginFrame(base::TimeTicks frame_time, 61 void LayerHost::BeginFrameSoon() {
56 base::TimeTicks deadline) { 62 base::MessageLoop::current()->PostTask(
63 FROM_HERE,
64 base::Bind(&LayerHost::BeginFrame, weak_factory_.GetWeakPtr()));
65 }
57 66
67 void LayerHost::BeginFrame() {
58 TRACE_EVENT0("sky", "LayerHost::BeginFrame"); 68 TRACE_EVENT0("sky", "LayerHost::BeginFrame");
59 69
60 DCHECK_EQ(state_, kWaitingForBeginFrame); 70 DCHECK(frame_requested_);
61 state_ = kProducingFrame; 71 frame_requested_ = false;
62 client_->BeginFrame(frame_time); 72
73 DCHECK_EQ(state_, kReadyForFrame);
74 state_ = kWaitingForFrameAcknowldgement;
75
76 client_->BeginFrame(base::TimeTicks::Now());
63 77
64 { 78 {
65 mojo::GaneshContext::Scope scope(&ganesh_context_); 79 mojo::GaneshContext::Scope scope(&ganesh_context_);
66 ganesh_context_.gr()->resetContext(); 80 ganesh_context_.gr()->resetContext();
67 root_layer_->Display(); 81 root_layer_->Display();
68 } 82 }
69 83
70 Upload(root_layer_.get()); 84 Upload(root_layer_.get());
71
72 if (state_ == kProducingFrame)
73 state_ = kIdle;
74 } 85 }
75 86
76 void LayerHost::Upload(Layer* layer) { 87 void LayerHost::Upload(Layer* layer) {
77 TRACE_EVENT0("sky", "LayerHost::Upload"); 88 TRACE_EVENT0("sky", "LayerHost::Upload");
78 89
79 if (!surface_holder_.IsReadyForFrame()) {
80 if (state_ == kProducingFrame) {
81 // Currently we use a timer to drive the BeginFrame cycle, which means we
82 // can produce frames before the surfaces service is ready to receive
83 // frames from us. In that situation, we wait for surfaces before
84 // uploading the frame. The upload will actually happen when the surface
85 // id is available (i.e., in OnSurfaceIdAvailable). If SetNeedsAnimate is
86 // called before then, we'll go back into the kWaitingForBeginFrame state
87 // and defer to the timer again.
88 //
89 // We can avoid this complexity if we use feedback from the surfaces
90 // service to drive the BeginFrame cycle. In that approach, we wouldn't
91 // get here before we've attached to a surface.
92 state_ = kWaitingForSurfaceToUploadFrame;
93 }
94 return;
95 }
96
97 gfx::Size size = layer->size(); 90 gfx::Size size = layer->size();
98 surface_holder_.SetSize(size); 91 surface_holder_.SetSize(size);
99 92
100 mojo::FramePtr frame = mojo::Frame::New(); 93 mojo::FramePtr frame = mojo::Frame::New();
101 frame->resources.resize(0u); 94 frame->resources.resize(0u);
102 95
103 mojo::Rect bounds; 96 mojo::Rect bounds;
104 bounds.width = size.width(); 97 bounds.width = size.width();
105 bounds.height = size.height(); 98 bounds.height = size.height();
106 mojo::PassPtr pass = mojo::CreateDefaultPass(1, bounds); 99 mojo::PassPtr pass = mojo::CreateDefaultPass(1, bounds);
(...skipping 27 matching lines...) Expand all
134 texture_state->background_color->rgba = 0; 127 texture_state->background_color->rgba = 0;
135 for (int i = 0; i < 4; ++i) 128 for (int i = 0; i < 4; ++i)
136 texture_state->vertex_opacity.push_back(1.f); 129 texture_state->vertex_opacity.push_back(1.f);
137 texture_state->flipped = false; 130 texture_state->flipped = false;
138 131
139 frame->resources.push_back(resource.Pass()); 132 frame->resources.push_back(resource.Pass());
140 quad->texture_quad_state = texture_state.Pass(); 133 quad->texture_quad_state = texture_state.Pass();
141 pass->quads.push_back(quad.Pass()); 134 pass->quads.push_back(quad.Pass());
142 135
143 frame->passes.push_back(pass.Pass()); 136 frame->passes.push_back(pass.Pass());
144 surface_holder_.SubmitFrame(frame.Pass()); 137 surface_holder_.SubmitFrame(
138 frame.Pass(),
139 base::Bind(&LayerHost::DidCompleteFrame, weak_factory_.GetWeakPtr()));
140 }
141
142 void LayerHost::DidCompleteFrame() {
143 DCHECK_EQ(state_, kWaitingForFrameAcknowldgement);
144 state_ = kReadyForFrame;
145 if (frame_requested_)
146 BeginFrame();
145 } 147 }
146 148
147 } // namespace sky 149 } // namespace sky
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698