| Index: ppapi/proxy/compositor_resource.cc
|
| diff --git a/ppapi/proxy/compositor_resource.cc b/ppapi/proxy/compositor_resource.cc
|
| index 497e58a5e6020b4ceef9c562453f7aae3944f762..3ada734849839aca56078ac7e3859b6d574df1a6 100644
|
| --- a/ppapi/proxy/compositor_resource.cc
|
| +++ b/ppapi/proxy/compositor_resource.cc
|
| @@ -4,32 +4,131 @@
|
|
|
| #include "ppapi/proxy/compositor_resource.h"
|
|
|
| +#include "base/logging.h"
|
| +#include "ppapi/proxy/ppapi_messages.h"
|
| +
|
| namespace ppapi {
|
| namespace proxy {
|
|
|
| CompositorResource::CompositorResource(Connection connection,
|
| PP_Instance instance)
|
| - : PluginResource(connection, instance) {
|
| + : PluginResource(connection, instance),
|
| + layer_reset_(true),
|
| + last_resource_id_(0) {
|
| + SendCreate(RENDERER, PpapiHostMsg_Compositor_Create());
|
| }
|
|
|
| CompositorResource::~CompositorResource() {
|
| + ResetLayersInternal();
|
| }
|
|
|
| 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() {
|
| - return 0;
|
| + 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) {
|
| - return PP_ERROR_NOTSUPPORTED;
|
| + 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() {
|
| - return PP_ERROR_NOTSUPPORTED;
|
| + if (IsInProgress())
|
| + return PP_ERROR_INPROGRESS;
|
| + ResetLayersInternal();
|
| + 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,
|
| + uint32_t sync_point,
|
| + 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(sync_point, is_lost);
|
| + release_callback_map_.erase(it);
|
| +}
|
| +
|
| +void CompositorResource::ResetLayersInternal() {
|
| + for (LayerList::iterator it = layers_.begin();
|
| + it != layers_.end(); ++it) {
|
| + ReleaseCallback release_callback = (*it)->release_callback();
|
| + if (!release_callback.is_null()) {
|
| + release_callback.Run(0, false);
|
| + (*it)->ResetReleaseCallback();
|
| + }
|
| + (*it)->Invalidate();
|
| + }
|
| +
|
| + layers_.clear();
|
| + layer_reset_ = true;
|
| }
|
|
|
| } // namespace proxy
|
|
|