1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file.
4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/pepper/pepper_compositor_host.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/logging.h"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/memory/shared_memory.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "cc/layers/layer.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "cc/layers/solid_color_layer.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "cc/layers/texture_layer.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "cc/resources/texture_mailbox.h"
136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "cc/trees/layer_tree_host.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/renderer/renderer_ppapi_host.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/pepper/gfx_conversion.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/pepper/host_globals.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/renderer/pepper/ppb_image_data_impl.h"
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/host/dispatch_host_message.h"
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/host/ppapi_host.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/enter.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h"
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/gfx/transform.h"
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::host::HostMessageContext;
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::EnterResourceNoLock;
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API;
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace content {
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int32_t VerifyCommittedLayer(
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData* old_layer,
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData* new_layer,
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<base::SharedMemory>* image_shm) {
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!new_layer->is_valid())
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->color) {
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Make sure the old layer is a color layer too.
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (old_layer && !old_layer->color)
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->texture) {
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (old_layer) {
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Make sure the old layer is a texture layer too.
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (!new_layer->texture)
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        return PP_ERROR_BADARGUMENT;
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // The mailbox should be same, if the resource_id is not changed.
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (new_layer->common.resource_id == old_layer->common.resource_id) {
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        if (new_layer->texture->mailbox != old_layer->texture->mailbox)
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          return PP_ERROR_BADARGUMENT;
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        return PP_OK;
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!new_layer->texture->mailbox.Verify())
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->image) {
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (old_layer) {
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Make sure the old layer is an image layer too.
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (!new_layer->image)
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        return PP_ERROR_BADARGUMENT;
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // The image data resource should be same, if the resource_id is not
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // changed.
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (new_layer->common.resource_id == old_layer->common.resource_id) {
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        if (new_layer->image->resource != old_layer->image->resource)
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          return PP_ERROR_BADARGUMENT;
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        return PP_OK;
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EnterResourceNoLock<PPB_ImageData_API> enter(new_layer->image->resource,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                 true);
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (enter.failed())
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_BADRESOURCE;
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(penghuang): support all kinds of image.
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PP_ImageDataDesc desc;
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (enter.object()->Describe(&desc) != PP_TRUE ||
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        desc.stride != desc.size.width * 4 ||
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL) {
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_BADARGUMENT;
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int handle;
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t byte_count;
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (enter.object()->GetSharedMemory(&handle, &byte_count) != PP_OK)
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_FAILED;
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_WIN)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::SharedMemoryHandle shm_handle;
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!::DuplicateHandle(::GetCurrentProcess(),
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           reinterpret_cast<base::SharedMemoryHandle>(handle),
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           ::GetCurrentProcess(),
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           &shm_handle,
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           0,
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           FALSE,
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                           DUPLICATE_SAME_ACCESS)) {
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_FAILED;
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    base::SharedMemoryHandle shm_handle(dup(handle), false);
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    image_shm->reset(new base::SharedMemory(shm_handle, true));
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!(*image_shm)->Map(desc.stride * desc.size.height)) {
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      image_shm->reset();
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_NOMEMORY;
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PepperCompositorHost::LayerData::LayerData(
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<cc::Layer>& cc,
127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData& pp) : cc_layer(cc), pp_layer(pp) {}
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PepperCompositorHost::LayerData::~LayerData() {}
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PepperCompositorHost::PepperCompositorHost(
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RendererPpapiHost* host,
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PP_Instance instance,
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PP_Resource resource)
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : ResourceHost(host->GetPpapiHost(), instance, resource),
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bound_instance_(NULL),
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      weak_factory_(this) {
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer_ = cc::Layer::Create();
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(penghuang): SetMasksToBounds() can be expensive if the layer is
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // transformed. Possibly better could be to explicitly clip the child layers
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // (by modifying their bounds).
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer_->SetMasksToBounds(true);
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer_->SetIsDrawable(true);
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)PepperCompositorHost::~PepperCompositorHost() {
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Unbind from the instance when destroyed if we're still bound.
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (bound_instance_)
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bound_instance_->BindGraphics(bound_instance_->pp_instance(), 0);
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool PepperCompositorHost::BindToInstance(
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PepperPluginInstanceImpl* new_instance) {
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_instance && new_instance->pp_instance() != pp_instance())
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;  // Can't bind other instance's contexts.
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (bound_instance_ == new_instance)
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return true;  // Rebinding the same device, nothing to do.
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (bound_instance_ && new_instance)
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return false;  // Can't change a bound device.
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bound_instance_ = new_instance;
1616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!bound_instance_)
1626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    SendCommitLayersReplyIfNecessary();
1636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return true;
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void PepperCompositorHost::ViewInitiatedPaint() {
1686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SendCommitLayersReplyIfNecessary();
1696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void PepperCompositorHost::ViewFlushedPaint() {}
1726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void PepperCompositorHost::ImageReleased(
1746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int32_t id,
1756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const scoped_ptr<base::SharedMemory>& shared_memory,
1766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    uint32_t sync_point,
1776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    bool is_lost) {
1786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ResourceReleased(id, sync_point, is_lost);
1796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void PepperCompositorHost::ResourceReleased(int32_t id,
1826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                            uint32_t sync_point,
1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                            bool is_lost) {
1846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  host()->SendUnsolicitedReply(
1856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      pp_resource(),
1866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      PpapiPluginMsg_Compositor_ReleaseResource(id, sync_point, is_lost));
1876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
1886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
1896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void PepperCompositorHost::SendCommitLayersReplyIfNecessary() {
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!commit_layers_reply_context_.is_valid())
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  host()->SendReply(commit_layers_reply_context_,
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    PpapiPluginMsg_Compositor_CommitLayersReply());
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  commit_layers_reply_context_ = ppapi::host::ReplyMessageContext();
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void PepperCompositorHost::UpdateLayer(
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<cc::Layer>& layer,
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData* old_layer,
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData* new_layer,
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<base::SharedMemory> image_shm) {
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Always update properties on cc::Layer, because cc::Layer
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // will ignore any setting with unchanged value.
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetIsDrawable(true);
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetBlendMode(SkXfermode::kSrcOver_Mode);
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetOpacity(new_layer->common.opacity);
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetBounds(PP_ToGfxSize(new_layer->common.size));
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetTransformOrigin(gfx::Point3F(new_layer->common.size.width / 2,
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                         new_layer->common.size.height / 2,
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                         0.0f));
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Transform transform(gfx::Transform::kSkipInitialization);
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  transform.matrix().setColMajorf(new_layer->common.transform.matrix);
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  layer->SetTransform(transform);
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Consider a (0,0,0,0) rect as no clip rect.
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->common.clip_rect.point.x != 0 ||
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new_layer->common.clip_rect.point.y != 0 ||
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new_layer->common.clip_rect.size.width != 0 ||
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      new_layer->common.clip_rect.size.height != 0) {
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<cc::Layer> clip_parent = layer->parent();
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (clip_parent.get() == layer_.get()) {
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Create a clip parent layer, if it does not exist.
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      clip_parent = cc::Layer::Create();
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      clip_parent->SetMasksToBounds(true);
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      clip_parent->SetIsDrawable(true);
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      layer_->ReplaceChild(layer.get(), clip_parent);
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      clip_parent->AddChild(layer);
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    gfx::Point position = PP_ToGfxPoint(new_layer->common.clip_rect.point);
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    clip_parent->SetPosition(position);
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    clip_parent->SetBounds(PP_ToGfxSize(new_layer->common.clip_rect.size));
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->SetPosition(gfx::Point(-position.x(), -position.y()));
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (layer->parent() != layer_.get()) {
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Remove the clip parent layer.
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer_->ReplaceChild(layer->parent(), layer);
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->SetPosition(gfx::Point());
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->color) {
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer->SetBackgroundColor(SkColorSetARGBMacro(
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->color->alpha * 255,
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->color->red * 255,
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->color->green * 255,
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->color->blue * 255));
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->texture) {
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<cc::TextureLayer> texture_layer(
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        static_cast<cc::TextureLayer*>(layer.get()));
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!old_layer ||
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->common.resource_id != old_layer->common.resource_id) {
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      cc::TextureMailbox mailbox(new_layer->texture->mailbox,
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                 new_layer->texture->target,
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 new_layer->texture->sync_point);
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      texture_layer->SetTextureMailbox(mailbox,
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          cc::SingleReleaseCallback::Create(
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              base::Bind(&PepperCompositorHost::ResourceReleased,
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         weak_factory_.GetWeakPtr(),
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         new_layer->common.resource_id)));
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // TODO(penghuang): get a damage region from the application and
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // pass it to SetNeedsDisplayRect().
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      texture_layer->SetNeedsDisplay();
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    texture_layer->SetPremultipliedAlpha(new_layer->texture->premult_alpha);
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    gfx::RectF rect = PP_ToGfxRectF(new_layer->texture->source_rect);
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    texture_layer->SetUV(rect.origin(), rect.bottom_right());
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (new_layer->image) {
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!old_layer ||
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        new_layer->common.resource_id != old_layer->common.resource_id) {
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_refptr<cc::TextureLayer> image_layer(
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          static_cast<cc::TextureLayer*>(layer.get()));
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EnterResourceNoLock<PPB_ImageData_API> enter(new_layer->image->resource,
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                   true);
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK(enter.succeeded());
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // TODO(penghuang): support all kinds of image.
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PP_ImageDataDesc desc;
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PP_Bool rv = enter.object()->Describe(&desc);
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK_EQ(rv, PP_TRUE);
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK_EQ(desc.stride, desc.size.width * 4);
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      DCHECK_EQ(desc.format, PP_IMAGEDATAFORMAT_RGBA_PREMUL);
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      cc::TextureMailbox mailbox(image_shm.get(),
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 PP_ToGfxSize(desc.size));
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      image_layer->SetTextureMailbox(mailbox,
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          cc::SingleReleaseCallback::Create(
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              base::Bind(&PepperCompositorHost::ImageReleased,
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         weak_factory_.GetWeakPtr(),
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         new_layer->common.resource_id,
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         base::Passed(&image_shm))));
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // TODO(penghuang): get a damage region from the application and
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // pass it to SetNeedsDisplayRect().
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      image_layer->SetNeedsDisplay();
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // ImageData is always premultiplied alpha.
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      image_layer->SetPremultipliedAlpha(true);
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Should not be reached.
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  NOTREACHED();
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int32_t PepperCompositorHost::OnResourceMessageReceived(
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const IPC::Message& msg,
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    HostMessageContext* context) {
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperCompositorHost, msg)
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PPAPI_DISPATCH_HOST_RESOURCE_CALL(
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      PpapiHostMsg_Compositor_CommitLayers, OnHostMsgCommitLayers)
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return ppapi::host::ResourceHost::OnResourceMessageReceived(msg, context);
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool PepperCompositorHost::IsCompositorHost() {
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return true;
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int32_t PepperCompositorHost::OnHostMsgCommitLayers(
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    HostMessageContext* context,
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::vector<ppapi::CompositorLayerData>& layers,
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool reset) {
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (commit_layers_reply_context_.is_valid())
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<scoped_ptr<base::SharedMemory>[]> image_shms;
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (layers.size() > 0) {
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    image_shms.reset(new scoped_ptr<base::SharedMemory>[layers.size()]);
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!image_shms)
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_ERROR_NOMEMORY;
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Verfiy the layers first, if an error happens, we will return the error to
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // plugin and keep current layers set by the previous CommitLayers()
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // unchanged.
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    for (size_t i = 0; i < layers.size(); ++i) {
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ppapi::CompositorLayerData* old_layer = NULL;
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (!reset && i < layers_.size())
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        old_layer = &layers_[i].pp_layer;
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      int32_t rv = VerifyCommittedLayer(old_layer, &layers[i], &image_shms[i]);
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (rv != PP_OK)
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        return rv;
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // ResetLayers() has been called, we need rebuild layer stack.
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (reset) {
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layer_->RemoveAllChildren();
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    layers_.clear();
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < layers.size(); ++i) {
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ppapi::CompositorLayerData* pp_layer = &layers[i];
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LayerData* data = i >= layers_.size() ? NULL : &layers_[i];
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!data || data->cc_layer.get());
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_refptr<cc::Layer> cc_layer = data ? data->cc_layer : NULL;
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ppapi::CompositorLayerData* old_layer = data ? &data->pp_layer : NULL;
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!cc_layer.get()) {
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (pp_layer->color)
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        cc_layer = cc::SolidColorLayer::Create();
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      else if (pp_layer->texture || pp_layer->image)
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        cc_layer = cc::TextureLayer::CreateForMailbox(NULL);
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      layer_->AddChild(cc_layer);
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    UpdateLayer(cc_layer, old_layer, pp_layer, image_shms[i].Pass());
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (old_layer)
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      *old_layer = *pp_layer;
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    else
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      layers_.push_back(LayerData(cc_layer, *pp_layer));
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // We need to force a commit for each CommitLayers() call, even if no layers
3786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // changed since the last call to CommitLayers(). This is so
3796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // WiewInitiatedPaint() will always be called.
3806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (layer_->layer_tree_host())
3816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    layer_->layer_tree_host()->SetNeedsCommit();
3826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // If the host is not bound to the instance, return PP_OK immediately.
3846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!bound_instance_)
3856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return PP_OK;
3866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
3876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  commit_layers_reply_context_ = context->MakeReplyMessageContext();
388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace content
392