mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Previously, there was no way for clients of the surfaces service to appropriately rate-limit their frame submissions. We tried using the "return resources" signal to rate-limit, but that's really a measure of how quickly you're submitting new resources rather than how quickly the system is putting up frames. Currently, only the Sky compositor listens to this signal. Using this signal, we're able to run sky/examples/spinning-square.sky in sync with the surfaces service (that is, submitting exactly one frames every 17ms). R=jamesr@chromium.org Review URL: https://codereview.chromium.org/756673004
78 lines
2.4 KiB
C++
78 lines
2.4 KiB
C++
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "sky/compositor/surface_holder.h"
|
|
|
|
#include "base/bind.h"
|
|
#include "base/message_loop/message_loop.h"
|
|
#include "mojo/converters/geometry/geometry_type_converters.h"
|
|
#include "mojo/public/cpp/application/connect.h"
|
|
#include "mojo/public/interfaces/application/shell.mojom.h"
|
|
#include "sky/compositor/surface_allocator.h"
|
|
|
|
namespace sky {
|
|
|
|
SurfaceHolder::Client::~Client() {
|
|
}
|
|
|
|
SurfaceHolder::SurfaceHolder(Client* client, mojo::Shell* shell)
|
|
: client_(client), weak_factory_(this) {
|
|
mojo::ServiceProviderPtr service_provider;
|
|
shell->ConnectToApplication("mojo:surfaces_service",
|
|
mojo::GetProxy(&service_provider));
|
|
mojo::ConnectToService(service_provider.get(), &surfaces_service_);
|
|
|
|
surfaces_service_->CreateSurfaceConnection(base::Bind(
|
|
&SurfaceHolder::OnSurfaceConnectionCreated, weak_factory_.GetWeakPtr()));
|
|
}
|
|
|
|
SurfaceHolder::~SurfaceHolder() {
|
|
if (surface_ && surface_id_)
|
|
surface_->DestroySurface(surface_id_.Clone());
|
|
}
|
|
|
|
bool SurfaceHolder::IsReadyForFrame() const {
|
|
return surface_;
|
|
}
|
|
|
|
void SurfaceHolder::SubmitFrame(mojo::FramePtr frame,
|
|
const base::Closure& callback) {
|
|
surface_->SubmitFrame(surface_id_.Clone(), frame.Pass(), callback);
|
|
}
|
|
|
|
void SurfaceHolder::SetSize(const gfx::Size& size) {
|
|
if (surface_id_ && size_ == size)
|
|
return;
|
|
|
|
if (surface_id_) {
|
|
surface_->DestroySurface(surface_id_.Clone());
|
|
} else {
|
|
surface_id_ = mojo::SurfaceId::New();
|
|
}
|
|
|
|
surface_id_->id = surface_allocator_->CreateSurfaceId();
|
|
surface_->CreateSurface(surface_id_.Clone(), mojo::Size::From(size));
|
|
size_ = size;
|
|
|
|
client_->OnSurfaceIdAvailable(surface_id_.Clone());
|
|
}
|
|
|
|
void SurfaceHolder::ReturnResources(
|
|
mojo::Array<mojo::ReturnedResourcePtr> resources) {
|
|
// TODO(abarth): The surface service shouldn't spam us with empty calls.
|
|
if (!resources.size())
|
|
return;
|
|
client_->ReturnResources(resources.Pass());
|
|
}
|
|
|
|
void SurfaceHolder::OnSurfaceConnectionCreated(mojo::SurfacePtr surface,
|
|
uint32_t id_namespace) {
|
|
surface_ = surface.Pass();
|
|
surface_.set_client(this);
|
|
surface_allocator_.reset(new SurfaceAllocator(id_namespace));
|
|
client_->OnSurfaceConnectionCreated();
|
|
}
|
|
|
|
} // namespace sky
|