1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/proxy/compositor_resource.h"
7 #include "base/logging.h"
8 #include "ppapi/proxy/ppapi_messages.h"
9 #include "ppapi/thunk/enter.h"
14 CompositorResource::CompositorResource(Connection connection
,
16 : PluginResource(connection
, instance
),
18 last_resource_id_(0) {
19 SendCreate(RENDERER
, PpapiHostMsg_Compositor_Create());
22 bool CompositorResource::IsInProgress() const {
23 ProxyLock::AssertAcquiredDebugOnly();
24 return TrackedCallback::IsPending(commit_callback_
);
27 int32_t CompositorResource::GenerateResourceId() const {
28 ProxyLock::AssertAcquiredDebugOnly();
29 return ++last_resource_id_
;
32 CompositorResource::~CompositorResource() {
33 ResetLayersInternal(true);
35 // Abort all release callbacks.
36 for (ReleaseCallbackMap::iterator it
= release_callback_map_
.begin();
37 it
!= release_callback_map_
.end(); ++it
) {
38 if (!it
->second
.is_null())
39 it
->second
.Run(PP_ERROR_ABORTED
, 0, false);
43 thunk::PPB_Compositor_API
* CompositorResource::AsPPB_Compositor_API() {
47 void CompositorResource::OnReplyReceived(
48 const ResourceMessageReplyParams
& params
,
49 const IPC::Message
& msg
) {
50 PPAPI_BEGIN_MESSAGE_MAP(CompositorResource
, msg
)
51 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL(
52 PpapiPluginMsg_Compositor_ReleaseResource
,
53 OnPluginMsgReleaseResource
)
54 PPAPI_DISPATCH_PLUGIN_RESOURCE_CALL_UNHANDLED(
55 PluginResource::OnReplyReceived(params
, msg
))
56 PPAPI_END_MESSAGE_MAP()
59 PP_Resource
CompositorResource::AddLayer() {
60 scoped_refptr
<CompositorLayerResource
> resource(new CompositorLayerResource(
61 connection(), pp_instance(), this));
62 layers_
.push_back(resource
);
63 return resource
->GetReference();
66 int32_t CompositorResource::CommitLayers(
67 const scoped_refptr
<ppapi::TrackedCallback
>& callback
) {
69 return PP_ERROR_INPROGRESS
;
71 std::vector
<CompositorLayerData
> layers
;
72 layers
.reserve(layers_
.size());
74 for (LayerList::const_iterator it
= layers_
.begin();
75 it
!= layers_
.end(); ++it
) {
76 if ((*it
)->data().is_null())
77 return PP_ERROR_FAILED
;
78 layers
.push_back((*it
)->data());
81 commit_callback_
= callback
;
82 Call
<PpapiPluginMsg_Compositor_CommitLayersReply
>(
84 PpapiHostMsg_Compositor_CommitLayers(layers
, layer_reset_
),
85 base::Bind(&CompositorResource::OnPluginMsgCommitLayersReply
,
86 base::Unretained(this)),
89 return PP_OK_COMPLETIONPENDING
;
92 int32_t CompositorResource::ResetLayers() {
94 return PP_ERROR_INPROGRESS
;
96 ResetLayersInternal(false);
100 void CompositorResource::OnPluginMsgCommitLayersReply(
101 const ResourceMessageReplyParams
& params
) {
102 if (!TrackedCallback::IsPending(commit_callback_
))
105 // On success, we put layers' release_callbacks into a map,
106 // otherwise we will do nothing. So plugin may change layers and
107 // call CommitLayers() again.
108 if (params
.result() == PP_OK
) {
109 layer_reset_
= false;
110 for (LayerList::iterator it
= layers_
.begin();
111 it
!= layers_
.end(); ++it
) {
112 ReleaseCallback release_callback
= (*it
)->release_callback();
113 if (!release_callback
.is_null()) {
114 release_callback_map_
.insert(ReleaseCallbackMap::value_type(
115 (*it
)->data().common
.resource_id
, release_callback
));
116 (*it
)->ResetReleaseCallback();
121 scoped_refptr
<TrackedCallback
> callback
;
122 callback
.swap(commit_callback_
);
123 callback
->Run(params
.result());
126 void CompositorResource::OnPluginMsgReleaseResource(
127 const ResourceMessageReplyParams
& params
,
131 ReleaseCallbackMap::iterator it
= release_callback_map_
.find(id
);
132 DCHECK(it
!= release_callback_map_
.end()) <<
133 "Can not found release_callback_ by id(" << id
<< ")!";
134 it
->second
.Run(PP_OK
, sync_point
, is_lost
);
135 release_callback_map_
.erase(it
);
138 void CompositorResource::ResetLayersInternal(bool is_aborted
) {
139 for (LayerList::iterator it
= layers_
.begin();
140 it
!= layers_
.end(); ++it
) {
141 ReleaseCallback release_callback
= (*it
)->release_callback();
142 if (!release_callback
.is_null()) {
143 release_callback
.Run(is_aborted
? PP_ERROR_ABORTED
: PP_OK
, 0, false);
144 (*it
)->ResetReleaseCallback();