Plugin Power Saver: Force SW rendering for peripheral plugins.
[chromium-blink-merge.git] / ppapi / proxy / compositor_resource.cc
blob443d7a949e977bab3394e8e7c0fe181d02eed7ac
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"
11 namespace ppapi {
12 namespace proxy {
14 CompositorResource::CompositorResource(Connection connection,
15 PP_Instance instance)
16 : PluginResource(connection, instance),
17 layer_reset_(true),
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() {
44 return this;
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) {
68 if (IsInProgress())
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>(
83 RENDERER,
84 PpapiHostMsg_Compositor_CommitLayers(layers, layer_reset_),
85 base::Bind(&CompositorResource::OnPluginMsgCommitLayersReply,
86 base::Unretained(this)),
87 callback);
89 return PP_OK_COMPLETIONPENDING;
92 int32_t CompositorResource::ResetLayers() {
93 if (IsInProgress())
94 return PP_ERROR_INPROGRESS;
96 ResetLayersInternal(false);
97 return PP_OK;
100 void CompositorResource::OnPluginMsgCommitLayersReply(
101 const ResourceMessageReplyParams& params) {
102 if (!TrackedCallback::IsPending(commit_callback_))
103 return;
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,
128 int32_t id,
129 uint32_t sync_point,
130 bool is_lost) {
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();
146 (*it)->Invalidate();
149 layers_.clear();
150 layer_reset_ = true;
153 } // namespace proxy
154 } // namespace ppapi