1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// 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 "ppapi/proxy/compositor_resource.h"
#include "base/logging.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/thunk/enter.h"
namespace ppapi {
namespace proxy {
CompositorResource::CompositorResource(Connection connection,
PP_Instance instance)
: PluginResource(connection, instance),
layer_reset_(true),
last_resource_id_(0) {
SendCreate(RENDERER, PpapiHostMsg_Compositor_Create());
}
bool CompositorResource::IsInProgress() const {
ProxyLock::AssertAcquiredDebugOnly();
return TrackedCallback::IsPending(commit_callback_);
}
int32_t CompositorResource::GenerateResourceId() const {
ProxyLock::AssertAcquiredDebugOnly();
return ++last_resource_id_;
}
CompositorResource::~CompositorResource() {
ResetLayersInternal(true);
// Abort all release callbacks.
for (ReleaseCallbackMap::iterator it = release_callback_map_.begin();
it != release_callback_map_.end(); ++it) {
if (!it->second.is_null())
it->second.Run(PP_ERROR_ABORTED, gpu::SyncToken(), false);
}
}
thunk::PPB_Compositor_API* CompositorResource::AsPPB_Compositor_API() {
return this;
}
void CompositorResource::OnReplyReceived(
const ResourceMessageReplyParams& params,
const IPC::Message& msg) {
PPAPI_BEGIN_MESSAGE_MAP(CompositorResource, msg)
PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
PpapiPluginMsg_Compositor_ReleaseResource,
OnPluginMsgReleaseResource)
PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
PluginResource::OnReplyReceived(params, msg))
PPAPI_END_MESSAGE_MAP()
}
PP_Resource CompositorResource::AddLayer() {
scoped_refptr<CompositorLayerResource> resource(new CompositorLayerResource(
connection(), pp_instance(), this));
layers_.push_back(resource);
return resource->GetReference();
}
int32_t CompositorResource::CommitLayers(
const scoped_refptr<ppapi::TrackedCallback>& callback) {
if (IsInProgress())
return PP_ERROR_INPROGRESS;
std::vector<CompositorLayerData> layers;
layers.reserve(layers_.size());
for (LayerList::const_iterator it = layers_.begin();
it != layers_.end(); ++it) {
if ((*it)->data().is_null())
return PP_ERROR_FAILED;
layers.push_back((*it)->data());
}
commit_callback_ = callback;
Call<PpapiPluginMsg_Compositor_CommitLayersReply>(
RENDERER,
PpapiHostMsg_Compositor_CommitLayers(layers, layer_reset_),
base::Bind(&CompositorResource::OnPluginMsgCommitLayersReply,
base::Unretained(this)),
callback);
return PP_OK_COMPLETIONPENDING;
}
int32_t CompositorResource::ResetLayers() {
if (IsInProgress())
return PP_ERROR_INPROGRESS;
ResetLayersInternal(false);
return PP_OK;
}
void CompositorResource::OnPluginMsgCommitLayersReply(
const ResourceMessageReplyParams& params) {
if (!TrackedCallback::IsPending(commit_callback_))
return;
// On success, we put layers' release_callbacks into a map,
// otherwise we will do nothing. So plugin may change layers and
// call CommitLayers() again.
if (params.result() == PP_OK) {
layer_reset_ = false;
for (LayerList::iterator it = layers_.begin();
it != layers_.end(); ++it) {
ReleaseCallback release_callback = (*it)->release_callback();
if (!release_callback.is_null()) {
release_callback_map_.insert(ReleaseCallbackMap::value_type(
(*it)->data().common.resource_id, release_callback));
(*it)->ResetReleaseCallback();
}
}
}
scoped_refptr<TrackedCallback> callback;
callback.swap(commit_callback_);
callback->Run(params.result());
}
void CompositorResource::OnPluginMsgReleaseResource(
const ResourceMessageReplyParams& params,
int32_t id,
const gpu::SyncToken& sync_token,
bool is_lost) {
ReleaseCallbackMap::iterator it = release_callback_map_.find(id);
DCHECK(it != release_callback_map_.end()) <<
"Can not found release_callback_ by id(" << id << ")!";
it->second.Run(PP_OK, sync_token, is_lost);
release_callback_map_.erase(it);
}
void CompositorResource::ResetLayersInternal(bool is_aborted) {
for (LayerList::iterator it = layers_.begin();
it != layers_.end(); ++it) {
ReleaseCallback release_callback = (*it)->release_callback();
if (!release_callback.is_null()) {
release_callback.Run(is_aborted ? PP_ERROR_ABORTED : PP_OK,
gpu::SyncToken(), false);
(*it)->ResetReleaseCallback();
}
(*it)->Invalidate();
}
layers_.clear();
layer_reset_ = true;
}
} // namespace proxy
} // namespace ppapi
|