blob: 8c8ecde451b2e29005366d366fe36420a243af3d [file] [log] [blame]
// Copyright 2016 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 "blimp/engine/renderer/blimp_remote_compositor_bridge.h"
#include "cc/blimp/compositor_proto_state.h"
#include "cc/blimp/remote_compositor_bridge_client.h"
#include "cc/output/swap_promise.h"
#include "cc/proto/compositor_message.pb.h"
namespace blimp {
namespace engine {
BlimpRemoteCompositorBridge::BlimpRemoteCompositorBridge(
content::RemoteProtoChannel* remote_proto_channel,
scoped_refptr<base::SingleThreadTaskRunner> compositor_main_task_runner)
: RemoteCompositorBridge(std::move(compositor_main_task_runner)),
remote_proto_channel_(remote_proto_channel),
scheduler_(compositor_main_task_runner_.get(), this) {
remote_proto_channel_->SetProtoReceiver(this);
}
BlimpRemoteCompositorBridge::~BlimpRemoteCompositorBridge() {
remote_proto_channel_->SetProtoReceiver(nullptr);
}
void BlimpRemoteCompositorBridge::BindToClient(
cc::RemoteCompositorBridgeClient* client) {
DCHECK(!client_);
client_ = client;
}
void BlimpRemoteCompositorBridge::ScheduleMainFrame() {
scheduler_.ScheduleFrameUpdate();
}
void BlimpRemoteCompositorBridge::ProcessCompositorStateUpdate(
std::unique_ptr<cc::CompositorProtoState> compositor_proto_state) {
compositor_proto_state->compositor_message->set_client_state_update_ack(
client_state_update_ack_pending_);
client_state_update_ack_pending_ = false;
remote_proto_channel_->SendCompositorProto(
*compositor_proto_state->compositor_message);
scheduler_.DidSendFrameUpdateToClient();
// Activate the swap promises after the frame is queued.
for (const auto& swap_promise : compositor_proto_state->swap_promises)
swap_promise->DidActivate();
}
void BlimpRemoteCompositorBridge::OnProtoReceived(
std::unique_ptr<cc::proto::CompositorMessage> proto) {
if (proto->frame_ack())
scheduler_.DidReceiveFrameUpdateAck();
if (proto->has_client_state_update()) {
DCHECK(!client_state_update_ack_pending_);
client_->ApplyStateUpdateFromClient(proto->client_state_update());
// If applying the delta resulted in a frame request, run the main frame
// first so the ack sent to the client includes the frame with the deltas
// applied.
if (scheduler_.needs_frame_update()) {
client_state_update_ack_pending_ = true;
} else {
cc::proto::CompositorMessage message;
message.set_client_state_update_ack(true);
remote_proto_channel_->SendCompositorProto(message);
}
}
}
void BlimpRemoteCompositorBridge::StartFrameUpdate() {
client_->BeginMainFrame();
// If the frame resulted in an update to the client, the ack should have gone
// with it. If it is still pending, this means the main frame was aborted so
// send the ack now.
if (client_state_update_ack_pending_) {
client_state_update_ack_pending_ = false;
cc::proto::CompositorMessage message;
message.set_client_state_update_ack(true);
remote_proto_channel_->SendCompositorProto(message);
}
}
} // namespace engine
} // namespace blimp