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"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_implementation.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/proxy/compositor_resource.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/enter.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/ppb_graphics_3d_api.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using gpu::gles2::GLES2Implementation;
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::EnterResourceNoLock;
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::PPB_ImageData_API;
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using ppapi::thunk::PPB_Graphics3D_API;
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace ppapi {
2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace proxy {
2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace {
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)float clamp(float value) {
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return std::min(std::max(value, 0.0f), 1.0f);
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void OnTextureReleased(
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& layer,
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& context,
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t texture,
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback,
356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int32_t result,
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t sync_point,
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool is_lost) {
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!TrackedCallback::IsPending(release_callback))
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (result != PP_OK) {
426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    release_callback->Run(result);
436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    return;
446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  do {
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!sync_point)
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EnterResourceNoLock<PPB_Graphics3D_API> enter(context.get(), true);
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (enter.failed())
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      break;
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PPB_Graphics3D_Shared* graphics =
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        static_cast<PPB_Graphics3D_Shared*>(enter.object());
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    GLES2Implementation* gl = graphics->gles2_impl();
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    gl->WaitSyncPointCHROMIUM(sync_point);
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  } while (false);
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback->Run(is_lost ? PP_ERROR_FAILED : PP_OK);
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void OnImageReleased(
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& layer,
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const ScopedPPResource& image,
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback,
686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    int32_t result,
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    uint32_t sync_point,
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool is_lost) {
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!TrackedCallback::IsPending(release_callback))
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return;
736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  release_callback->Run(result);
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)CompositorLayerResource::CompositorLayerResource(
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Connection connection,
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PP_Instance instance,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const CompositorResource* compositor)
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : PluginResource(connection, instance),
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      compositor_(compositor),
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      source_size_(PP_MakeFloatSize(0.0f, 0.0f)) {
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CompositorLayerResource::~CompositorLayerResource() {
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(!compositor_);
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(release_callback_.is_null());
9046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)thunk::PPB_CompositorLayer_API*
9346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)CompositorLayerResource::AsPPB_CompositorLayer_API() {
9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return this;
9546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetColor(float red,
9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float green,
9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float blue,
10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          float alpha,
10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                                          const PP_Size* size) {
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!SetType(TYPE_COLOR))
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.color);
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size)
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->red = clamp(red);
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->green = clamp(green);
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->blue = clamp(blue);
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.color->alpha = clamp(alpha);
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = *size;
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetTexture(
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource context,
12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    uint32_t texture,
12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_Size* size,
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int32_t rv = CheckForSetTextureAndImage(TYPE_TEXTURE, release_callback);
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (rv != PP_OK)
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return rv;
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.texture);
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (enter.failed())
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size || size->width <= 0 || size->height <= 0)
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PPB_Graphics3D_Shared* graphics =
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      static_cast<PPB_Graphics3D_Shared*>(enter.object());
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GLES2Implementation* gl = graphics->gles2_impl();
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Generate a Mailbox for the texture.
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gl->GenMailboxCHROMIUM(
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reinterpret_cast<GLbyte*>(data_.texture->mailbox.name));
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gl->ProduceTextureDirectCHROMIUM(
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      texture, GL_TEXTURE_2D,
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      reinterpret_cast<const GLbyte*>(data_.texture->mailbox.name));
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set the source size to (1, 1). It will be used to verify the source_rect
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // passed to SetSourceRect().
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = *size;
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.resource_id = compositor_->GenerateResourceId();
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->sync_point = gl->InsertSyncPointCHROMIUM();
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.texture->source_rect.size = source_size_;
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the PP_Resource of this layer is released by the plugin, the
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // release_callback will be aborted immediately, but the texture or image
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // in this layer may still being used by chromium compositor. So we have to
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // use ScopedPPResource to keep this resource alive until the texture or image
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // is released by the chromium compositor.
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback_ = base::Bind(
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &OnTextureReleased,
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(pp_resource()), // Keep layer alive.
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(context), // Keep context alive
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      texture,
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      release_callback);
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetImage(
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    PP_Resource image_data,
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_Size* size,
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int32_t rv = CheckForSetTextureAndImage(TYPE_IMAGE, release_callback);
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (rv != PP_OK)
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return rv;
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(data_.image);
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (enter.failed())
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PP_ImageDataDesc desc;
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!enter.object()->Describe(&desc))
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(penghuang): Support image which width * 4 != stride.
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (desc.size.width * 4 != desc.stride)
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // TODO(penghuang): Support all formats.
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!size || size->width <= 0 || size->height <= 0)
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set the source size to image's size. It will be used to verify
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // the source_rect passed to SetSourceRect().
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.size = size ? *size : desc.size;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.resource_id = compositor_->GenerateResourceId();
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->resource = enter.resource()->host_resource().host_resource();
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.image->source_rect.size = source_size_;
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // If the PP_Resource of this layer is released by the plugin, the
2176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // release_callback will be aborted immediately, but the texture or image
2186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // in this layer may still being used by chromium compositor. So we have to
2196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // use ScopedPPResource to keep this resource alive until the texture or image
2206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // is released by the chromium compositor.
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  release_callback_ = base::Bind(
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &OnImageReleased,
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(pp_resource()), // Keep layer alive.
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ScopedPPResource(image_data), // Keep image_data alive.
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      release_callback);
226f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK_COMPLETIONPENDING;
22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) {
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
233f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
235f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetTransform(const float matrix[16]) {
242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::copy(matrix, matrix + 16, data_.common.transform.matrix);
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetOpacity(float opacity) {
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  data_.common.opacity = clamp(opacity);
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) {
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  switch (mode) {
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case PP_BLENDMODE_NONE:
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    case PP_BLENDMODE_SRC_OVER:
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.common.blend_mode = mode;
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return PP_OK;
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetSourceRect(
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const PP_FloatRect* rect) {
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)  if (!rect ||
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.x < 0.0f ||
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.y < 0.0f ||
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.x + rect->size.width > source_size_.width ||
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      rect->point.y + rect->size.height > source_size_.height) {
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.texture) {
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.texture->source_rect = *rect;
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.image) {
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.image->source_rect = *rect;
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) {
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!compositor_)
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (data_.texture) {
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    data_.texture->premult_alpha = PP_ToBool(premult);
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_OK;
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_ERROR_BADARGUMENT;
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool CompositorLayerResource::SetType(LayerType type) {
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_COLOR) {
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.color.reset(new CompositorLayerData::ColorLayer());
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.color;
325f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
326f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
327f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_TEXTURE) {
328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.texture.reset(new CompositorLayerData::TextureLayer());
330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.texture;
331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (type == TYPE_IMAGE) {
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (data_.is_null())
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      data_.image.reset(new CompositorLayerData::ImageLayer());
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return data_.image;
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Should not be reached.
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK(false);
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return false;
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)int32_t CompositorLayerResource::CheckForSetTextureAndImage(
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    LayerType type,
346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const scoped_refptr<TrackedCallback>& release_callback) {
3476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!compositor_)
348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
349f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (compositor_->IsInProgress())
351f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!SetType(type))
354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
356f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The layer's image has been set and it is not committed.
357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!release_callback_.is_null())
358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_INPROGRESS;
359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Do not allow using a block callback as a release callback.
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (release_callback->is_blocking())
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    return PP_ERROR_BADARGUMENT;
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return PP_OK;
36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace proxy
36846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}  // namespace ppapi
369