Enable the Sky compositor again
This CL fixes two bugs: 1) We need to enter the Ganesh context in order to destroy the GrContext. 2) We had a race condition whereby we'd try to upload a frame to a surface that didn't yet exist. This CL fixes that race by adding a state to LayerHost to wait for the surface to be created before trying to upload to it. R=esprehn@chromium.org Review URL: https://codereview.chromium.org/753643002
This commit is contained in:
@@ -15,6 +15,7 @@ namespace sky {
|
||||
|
||||
LayerHost::LayerHost(LayerHostClient* client)
|
||||
: client_(client),
|
||||
state_(kIdle),
|
||||
surface_holder_(this, client->GetShell()),
|
||||
gl_context_(mojo::GLContext::Create(client->GetShell())),
|
||||
ganesh_context_(gl_context_),
|
||||
@@ -29,6 +30,7 @@ LayerHost::~LayerHost() {
|
||||
|
||||
void LayerHost::SetNeedsAnimate() {
|
||||
scheduler_.SetNeedsFrame();
|
||||
state_ = kWaitingForBeginFrame;
|
||||
}
|
||||
|
||||
void LayerHost::SetRootLayer(scoped_refptr<Layer> layer) {
|
||||
@@ -39,6 +41,9 @@ void LayerHost::SetRootLayer(scoped_refptr<Layer> layer) {
|
||||
|
||||
void LayerHost::OnSurfaceIdAvailable(mojo::SurfaceIdPtr surface_id) {
|
||||
client_->OnSurfaceIdAvailable(surface_id.Pass());
|
||||
|
||||
if (state_ == kWaitingForSurfaceToUploadFrame)
|
||||
Upload(root_layer_.get());
|
||||
}
|
||||
|
||||
void LayerHost::ReturnResources(
|
||||
@@ -48,6 +53,8 @@ void LayerHost::ReturnResources(
|
||||
|
||||
void LayerHost::BeginFrame(base::TimeTicks frame_time,
|
||||
base::TimeTicks deadline) {
|
||||
DCHECK_EQ(state_, kWaitingForBeginFrame);
|
||||
state_ = kProducingFrame;
|
||||
client_->BeginFrame(frame_time);
|
||||
|
||||
{
|
||||
@@ -57,9 +64,30 @@ void LayerHost::BeginFrame(base::TimeTicks frame_time,
|
||||
}
|
||||
|
||||
Upload(root_layer_.get());
|
||||
|
||||
if (state_ == kProducingFrame)
|
||||
state_ = kIdle;
|
||||
}
|
||||
|
||||
void LayerHost::Upload(Layer* layer) {
|
||||
if (!surface_holder_.IsReadyForFrame()) {
|
||||
if (state_ == kProducingFrame) {
|
||||
// Currently we use a timer to drive the BeginFrame cycle, which means we
|
||||
// can produce frames before the surfaces service is ready to receive
|
||||
// frames from us. In that situation, we wait for surfaces before
|
||||
// uploading the frame. The upload will actually happen when the surface
|
||||
// id is available (i.e., in OnSurfaceIdAvailable). If SetNeedsAnimate is
|
||||
// called before then, we'll go back into the kWaitingForBeginFrame state
|
||||
// and defer to the timer again.
|
||||
//
|
||||
// We can avoid this complexity if we use feedback from the surfaces
|
||||
// service to drive the BeginFrame cycle. In that approach, we wouldn't
|
||||
// get here before we've attached to a surface.
|
||||
state_ = kWaitingForSurfaceToUploadFrame;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Size size = layer->size();
|
||||
surface_holder_.SetSize(size);
|
||||
|
||||
|
||||
@@ -41,6 +41,13 @@ class LayerHost : public SurfaceHolder::Client, public Scheduler::Client {
|
||||
void SetRootLayer(scoped_refptr<Layer> layer);
|
||||
|
||||
private:
|
||||
enum State {
|
||||
kIdle,
|
||||
kWaitingForBeginFrame,
|
||||
kProducingFrame,
|
||||
kWaitingForSurfaceToUploadFrame,
|
||||
};
|
||||
|
||||
// SurfaceHolder::Client
|
||||
void OnSurfaceIdAvailable(mojo::SurfaceIdPtr surface_id) override;
|
||||
void ReturnResources(
|
||||
@@ -53,6 +60,7 @@ class LayerHost : public SurfaceHolder::Client, public Scheduler::Client {
|
||||
void Upload(Layer* layer);
|
||||
|
||||
LayerHostClient* client_;
|
||||
State state_;
|
||||
SurfaceHolder surface_holder_;
|
||||
base::WeakPtr<mojo::GLContext> gl_context_;
|
||||
mojo::GaneshContext ganesh_context_;
|
||||
|
||||
@@ -28,10 +28,14 @@ SurfaceHolder::SurfaceHolder(Client* client, mojo::Shell* shell)
|
||||
}
|
||||
|
||||
SurfaceHolder::~SurfaceHolder() {
|
||||
if (surface_id_)
|
||||
if (surface_ && surface_id_)
|
||||
surface_->DestroySurface(surface_id_.Clone());
|
||||
}
|
||||
|
||||
bool SurfaceHolder::IsReadyForFrame() const {
|
||||
return surface_;
|
||||
}
|
||||
|
||||
void SurfaceHolder::SubmitFrame(mojo::FramePtr frame) {
|
||||
surface_->SubmitFrame(surface_id_.Clone(), frame.Pass());
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ class SurfaceHolder : public mojo::SurfaceClient {
|
||||
explicit SurfaceHolder(Client* client, mojo::Shell* shell);
|
||||
~SurfaceHolder() override;
|
||||
|
||||
bool IsReadyForFrame() const;
|
||||
|
||||
void SetSize(const gfx::Size& size);
|
||||
void SubmitFrame(mojo::FramePtr frame);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user