146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file.
446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ppapi/proxy/compositor_layer_resource.h"
646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/logging.h"
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "gpu/GLES2/gl2extchromium.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/proxy/compositor_resource.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/enter.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/ppb_graphics_3d_api.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using gpu::gles2::GLES2Implementation;
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::EnterResourceNoLock;
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API;
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::PPB_Graphics3D_API;
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ppapi {
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace proxy {
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)float clamp(float value) {
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return std::min(std::max(value, 0.0f), 1.0f);
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void OnTextureReleased(
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& layer,
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& context,
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t texture,
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback,
366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int32_t result,
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t sync_point,
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool is_lost) {
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!TrackedCallback::IsPending(release_callback))
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (result != PP_OK) {
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    release_callback->Run(result);
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  do {
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!sync_point)
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EnterResourceNoLock<PPB_Graphics3D_API> enter(context.get(), true);
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (enter.failed())
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PPB_Graphics3D_Shared* graphics =
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        static_cast<PPB_Graphics3D_Shared*>(enter.object());
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    GLES2Implementation* gl = graphics->gles2_impl();
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    gl->WaitSyncPointCHROMIUM(sync_point);
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } while (false);
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback->Run(is_lost ? PP_ERROR_FAILED : PP_OK);
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void OnImageReleased(
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& layer,
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& image,
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback,
696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int32_t result,
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t sync_point,
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool is_lost) {
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!TrackedCallback::IsPending(release_callback))
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  release_callback->Run(result);
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)CompositorLayerResource::CompositorLayerResource(
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Connection connection,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PP_Instance instance,
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const CompositorResource* compositor)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : PluginResource(connection, instance),
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      compositor_(compositor),
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      source_size_(PP_MakeFloatSize(0.0f, 0.0f)) {
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CompositorLayerResource::~CompositorLayerResource() {
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!compositor_);
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(release_callback_.is_null());
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)thunk::PPB_CompositorLayer_API*
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CompositorLayerResource::AsPPB_CompositorLayer_API() {
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return this;
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetColor(float red,
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float green,
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float blue,
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float alpha,
10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          const PP_Size* size) {
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!SetType(TYPE_COLOR))
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.color);
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size)
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->red = clamp(red);
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->green = clamp(green);
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->blue = clamp(blue);
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->alpha = clamp(alpha);
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = *size;
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)int32_t CompositorLayerResource::SetTexture0_1(
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    PP_Resource context,
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    uint32_t texture,
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const PP_Size* size,
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return SetTexture(context, GL_TEXTURE_2D, texture, size, release_callback);
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetTexture(
13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource context,
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    uint32_t target,
13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    uint32_t texture,
13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_Size* size,
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int32_t rv = CheckForSetTextureAndImage(TYPE_TEXTURE, release_callback);
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (rv != PP_OK)
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return rv;
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.texture);
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (enter.failed())
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (target != GL_TEXTURE_2D &&
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      target != GL_TEXTURE_EXTERNAL_OES &&
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      target != GL_TEXTURE_RECTANGLE_ARB) {
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size || size->width <= 0 || size->height <= 0)
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PPB_Graphics3D_Shared* graphics =
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      static_cast<PPB_Graphics3D_Shared*>(enter.object());
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GLES2Implementation* gl = graphics->gles2_impl();
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Generate a Mailbox for the texture.
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gl->GenMailboxCHROMIUM(
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reinterpret_cast<GLbyte*>(data_.texture->mailbox.name));
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gl->ProduceTextureDirectCHROMIUM(
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      texture, target,
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reinterpret_cast<const GLbyte*>(data_.texture->mailbox.name));
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set the source size to (1, 1). It will be used to verify the source_rect
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // passed to SetSourceRect().
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = *size;
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.resource_id = compositor_->GenerateResourceId();
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  data_.texture->target = target;
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->sync_point = gl->InsertSyncPointCHROMIUM();
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->source_rect.size = source_size_;
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the PP_Resource of this layer is released by the plugin, the
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // release_callback will be aborted immediately, but the texture or image
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // in this layer may still being used by chromium compositor. So we have to
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // use ScopedPPResource to keep this resource alive until the texture or image
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // is released by the chromium compositor.
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback_ = base::Bind(
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &OnTextureReleased,
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(pp_resource()), // Keep layer alive.
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(context), // Keep context alive
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      texture,
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      release_callback);
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetImage(
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource image_data,
19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_Size* size,
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int32_t rv = CheckForSetTextureAndImage(TYPE_IMAGE, release_callback);
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (rv != PP_OK)
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return rv;
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.image);
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (enter.failed())
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PP_ImageDataDesc desc;
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!enter.object()->Describe(&desc))
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(penghuang): Support image which width * 4 != stride.
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (desc.size.width * 4 != desc.stride)
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(penghuang): Support all formats.
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size || size->width <= 0 || size->height <= 0)
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set the source size to image's size. It will be used to verify
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // the source_rect passed to SetSourceRect().
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = size ? *size : desc.size;
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.resource_id = compositor_->GenerateResourceId();
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->resource = enter.resource()->host_resource().host_resource();
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->source_rect.size = source_size_;
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // If the PP_Resource of this layer is released by the plugin, the
2346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // release_callback will be aborted immediately, but the texture or image
2356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // in this layer may still being used by chromium compositor. So we have to
2366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // use ScopedPPResource to keep this resource alive until the texture or image
2376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // is released by the chromium compositor.
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback_ = base::Bind(
239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &OnImageReleased,
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(pp_resource()), // Keep layer alive.
241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(image_data), // Keep image_data alive.
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      release_callback);
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) {
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetTransform(const float matrix[16]) {
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::copy(matrix, matrix + 16, data_.common.transform.matrix);
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetOpacity(float opacity) {
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.opacity = clamp(opacity);
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) {
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
283f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  switch (mode) {
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case PP_BLENDMODE_NONE:
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case PP_BLENDMODE_SRC_OVER:
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.common.blend_mode = mode;
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_OK;
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetSourceRect(
29746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_FloatRect* rect) {
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!rect ||
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.x < 0.0f ||
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.y < 0.0f ||
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.x + rect->size.width > source_size_.width ||
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.y + rect->size.height > source_size_.height) {
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.texture) {
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.texture->source_rect = *rect;
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.image) {
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.image->source_rect = *rect;
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) {
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.texture) {
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.texture->premult_alpha = PP_ToBool(premult);
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool CompositorLayerResource::SetType(LayerType type) {
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_COLOR) {
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.color.reset(new CompositorLayerData::ColorLayer());
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.color;
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_TEXTURE) {
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.texture.reset(new CompositorLayerData::TextureLayer());
347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.texture;
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_IMAGE) {
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.image.reset(new CompositorLayerData::ImageLayer());
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.image;
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Should not be reached.
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(false);
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return false;
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int32_t CompositorLayerResource::CheckForSetTextureAndImage(
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LayerType type,
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
3646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!compositor_)
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!SetType(type))
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The layer's image has been set and it is not committed.
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!release_callback_.is_null())
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Do not allow using a block callback as a release callback.
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (release_callback->is_blocking())
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
38246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
38346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
38446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace proxy
38546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace ppapi
386