Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Unified Diff: ppapi/proxy/compositor_layer_resource.cc

Issue 298023004: [PPAPI] Compositor API implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compositor_api_def_new
Patch Set: Fix link issue Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/proxy/compositor_layer_resource.h ('k') | ppapi/proxy/compositor_resource.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/proxy/compositor_layer_resource.cc
diff --git a/ppapi/proxy/compositor_layer_resource.cc b/ppapi/proxy/compositor_layer_resource.cc
index 829ff187391503fd4141c9eb5a11a5459728eb42..fb1bbe5139aa863c14d697558e12f15a9beb6b28 100644
--- a/ppapi/proxy/compositor_layer_resource.cc
+++ b/ppapi/proxy/compositor_layer_resource.cc
@@ -4,15 +4,99 @@
#include "ppapi/proxy/compositor_layer_resource.h"
+#include "base/logging.h"
+#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "ppapi/proxy/compositor_resource.h"
+#include "ppapi/shared_impl/ppb_graphics_3d_shared.h"
+#include "ppapi/thunk/enter.h"
+#include "ppapi/thunk/ppb_graphics_3d_api.h"
+#include "ppapi/thunk/ppb_image_data_api.h"
+
+using gpu::gles2::GLES2Implementation;
+using ppapi::thunk::EnterResourceNoLock;
+using ppapi::thunk::PPB_ImageData_API;
+using ppapi::thunk::PPB_Graphics3D_API;
+
namespace ppapi {
namespace proxy {
-CompositorLayerResource::CompositorLayerResource(Connection connection,
- PP_Instance instance)
- : PluginResource(connection, instance) {
+namespace {
+
+class Scoped2DTextureBinder {
+ public:
+ Scoped2DTextureBinder(GLES2Implementation* gl, uint32_t id)
+ : gl_(gl), old_id_(-1) {
+ gl_->GetIntegerv(GL_TEXTURE_BINDING_2D, &old_id_);
+ gl_->BindTexture(GL_TEXTURE_2D, id);
+ }
+
+ ~Scoped2DTextureBinder() {
+ gl_->BindTexture(GL_TEXTURE_2D, old_id_);
+ }
+
+ private:
+ GLES2Implementation* gl_;
+ int32_t old_id_;
+};
+
+float clamp(float value) {
+ return std::min(std::max(value, 0.0f), 1.0f);
+}
+
+void OnTextureReleased(
+ const ScopedPPResource& layer,
+ const ScopedPPResource& context,
+ uint32_t texture,
+ const scoped_refptr<TrackedCallback>& release_callback,
+ uint32_t sync_point,
+ bool is_lost) {
+ if (!TrackedCallback::IsPending(release_callback))
+ return;
+
+ do {
+ if (!sync_point)
+ break;
+
+ EnterResourceNoLock<PPB_Graphics3D_API> enter(context.get(), true);
+ if (enter.failed())
+ break;
+
+ PPB_Graphics3D_Shared* graphics =
+ static_cast<PPB_Graphics3D_Shared*>(enter.object());
+
+ GLES2Implementation* gl = graphics->gles2_impl();
+ gl->WaitSyncPointCHROMIUM(sync_point);
+ } while (false);
+
+ release_callback->Run(is_lost ? PP_ERROR_FAILED : PP_OK);
+}
+
+void OnImageReleased(
+ const ScopedPPResource& layer,
+ const ScopedPPResource& image,
+ const scoped_refptr<TrackedCallback>& release_callback,
+ uint32_t sync_point,
+ bool is_lost) {
+ if (!TrackedCallback::IsPending(release_callback))
+ return;
+ release_callback->Run(PP_OK);
+}
+
+} // namespace
+
+CompositorLayerResource::CompositorLayerResource(
+ Connection connection,
+ PP_Instance instance,
+ const CompositorResource* compositor)
+ : PluginResource(connection, instance),
+ compositor_(compositor),
+ source_size_(PP_MakeFloatSize(0.0f, 0.0f)) {
}
CompositorLayerResource::~CompositorLayerResource() {
+ DCHECK(!compositor_);
+ DCHECK(release_callback_.is_null());
}
thunk::PPB_CompositorLayer_API*
@@ -25,47 +109,266 @@ int32_t CompositorLayerResource::SetColor(float red,
float blue,
float alpha,
const PP_Size* size) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ if (!SetType(TYPE_COLOR))
+ return PP_ERROR_BADARGUMENT;
+ DCHECK(data_.color);
+
+ if (!size)
+ return PP_ERROR_BADARGUMENT;
+
+
+ data_.color->red = clamp(red);
+ data_.color->green = clamp(green);
+ data_.color->blue = clamp(blue);
+ data_.color->alpha = clamp(alpha);
+ data_.common.size = *size;
+
+ return PP_OK;
}
int32_t CompositorLayerResource::SetTexture(
PP_Resource context,
uint32_t texture,
const PP_Size* size,
- const scoped_refptr<ppapi::TrackedCallback>& callback) {
- return PP_ERROR_NOTSUPPORTED;
+ const scoped_refptr<TrackedCallback>& release_callback) {
+ int32_t rv = CheckForSetTextureAndImage(TYPE_TEXTURE, release_callback);
+ if (rv != PP_OK)
+ return rv;
+ DCHECK(data_.texture);
+
+ EnterResourceNoLock<PPB_Graphics3D_API> enter(context, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+
+ if (!size || size->width <= 0 || size->height <= 0)
+ return PP_ERROR_BADARGUMENT;
+
+ PPB_Graphics3D_Shared* graphics =
+ static_cast<PPB_Graphics3D_Shared*>(enter.object());
+
+ GLES2Implementation* gl = graphics->gles2_impl();
+ Scoped2DTextureBinder scoped_2d_texture_binder(gl, texture);
+
+ // Generate a Mailbox for the texture.
+ gl->GenMailboxCHROMIUM(
+ reinterpret_cast<GLbyte*>(data_.texture->mailbox.name));
+ gl->ProduceTextureCHROMIUM(
+ GL_TEXTURE_2D,
+ reinterpret_cast<const GLbyte*>(data_.texture->mailbox.name));
+
+ // Set the source size to (1, 1). It will be used to verify the source_rect
+ // passed to SetSourceRect().
+ source_size_ = PP_MakeFloatSize(1.0f, 1.0f);
+
+ data_.common.size = *size;
+ data_.common.resource_id = compositor_->GenerateResourceId();
+ data_.texture->sync_point = gl->InsertSyncPointCHROMIUM();
+ data_.texture->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
+ data_.texture->source_rect.size = source_size_;
+
+ // If the PP_Resource of this layer is released by the plugin, the
+ // release_callback will be aborted immediately, but the texture or image
+ // in this layer may still being used by chromium compositor. So we have to
+ // use ScopedPPResource to keep this resource alive until the texture or image
+ // is released by the chromium compositor.
+ release_callback_ = base::Bind(
+ &OnTextureReleased,
+ ScopedPPResource(pp_resource()), // Keep layer alive.
+ ScopedPPResource(context), // Keep context alive
+ texture,
+ release_callback);
+
+ return PP_OK_COMPLETIONPENDING;
}
int32_t CompositorLayerResource::SetImage(
PP_Resource image_data,
const PP_Size* size,
- const scoped_refptr<ppapi::TrackedCallback>& callback) {
- return PP_ERROR_NOTSUPPORTED;
+ const scoped_refptr<TrackedCallback>& release_callback) {
+ int32_t rv = CheckForSetTextureAndImage(TYPE_IMAGE, release_callback);
+ if (rv != PP_OK)
+ return rv;
+ DCHECK(data_.image);
+
+ EnterResourceNoLock<PPB_ImageData_API> enter(image_data, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+
+ PP_ImageDataDesc desc;
+ if (!enter.object()->Describe(&desc))
+ return PP_ERROR_BADARGUMENT;
+
+ // TODO(penghuang): Support image which width * 4 != stride.
+ if (desc.size.width * 4 != desc.stride)
+ return PP_ERROR_BADARGUMENT;
+
+ // TODO(penghuang): Support all formats.
+ if (desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL)
+ return PP_ERROR_BADARGUMENT;
+
+ if (!size || size->width <= 0 || size->height <= 0)
+ return PP_ERROR_BADARGUMENT;
+
+ // Set the source size to image's size. It will be used to verify
+ // the source_rect passed to SetSourceRect().
+ source_size_ = PP_MakeFloatSize(desc.size.width, desc.size.height);
+
+ data_.common.size = size ? *size : desc.size;
+ data_.common.resource_id = compositor_->GenerateResourceId();
+ data_.image->resource = enter.resource()->host_resource().host_resource();
+ data_.image->source_rect.point = PP_MakeFloatPoint(0.0f, 0.0f);
+ data_.image->source_rect.size = source_size_;
+
+ release_callback_ = base::Bind(
+ &OnImageReleased,
+ ScopedPPResource(pp_resource()), // Keep layer alive.
+ ScopedPPResource(image_data), // Keep image_data alive.
+ release_callback);
+
+ return PP_OK_COMPLETIONPENDING;
}
int32_t CompositorLayerResource::SetClipRect(const PP_Rect* rect) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ data_.common.clip_rect = rect ? *rect : PP_MakeRectFromXYWH(0, 0, 0, 0);
+ return PP_OK;
}
int32_t CompositorLayerResource::SetTransform(const float matrix[16]) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ std::copy(matrix, matrix + 16, data_.common.transform.matrix);
+ return PP_OK;
}
int32_t CompositorLayerResource::SetOpacity(float opacity) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ data_.common.opacity = clamp(opacity);
+ return PP_OK;
}
int32_t CompositorLayerResource::SetBlendMode(PP_BlendMode mode) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ switch (mode) {
+ case PP_BLENDMODE_NONE:
+ case PP_BLENDMODE_SRC_OVER:
+ data_.common.blend_mode = mode;
+ return PP_OK;
+ }
+ return PP_ERROR_BADARGUMENT;
}
int32_t CompositorLayerResource::SetSourceRect(
const PP_FloatRect* rect) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ if (!rect ||
+ rect->point.x < 0.0f ||
+ rect->point.y < 0.0f ||
+ rect->point.x + rect->size.width > source_size_.width ||
+ rect->point.y + rect->size.height > source_size_.height) {
+ return PP_ERROR_BADARGUMENT;
+ }
+
+ if (data_.texture) {
+ data_.texture->source_rect = *rect;
+ return PP_OK;
+ }
+ if (data_.image) {
+ data_.image->source_rect = *rect;
+ return PP_OK;
+ }
+ return PP_ERROR_BADARGUMENT;
}
int32_t CompositorLayerResource::SetPremultipliedAlpha(PP_Bool premult) {
- return PP_ERROR_NOTSUPPORTED;
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ if (data_.texture) {
+ data_.texture->premult_alpha = PP_ToBool(premult);
+ return PP_OK;
+ }
+ return PP_ERROR_BADARGUMENT;
+}
+
+bool CompositorLayerResource::SetType(LayerType type) {
+ if (type == TYPE_COLOR) {
+ if (data_.is_null())
+ data_.color.reset(new CompositorLayerData::ColorLayer());
+ return data_.color;
+ }
+
+ if (type == TYPE_TEXTURE) {
+ if (data_.is_null())
+ data_.texture.reset(new CompositorLayerData::TextureLayer());
+ return data_.texture;
+ }
+
+ if (type == TYPE_IMAGE) {
+ if (data_.is_null())
+ data_.image.reset(new CompositorLayerData::ImageLayer());
+ return data_.image;
+ }
+
+ // Should not be reached.
+ DCHECK(false);
+ return false;
+}
+
+int32_t CompositorLayerResource::CheckForSetTextureAndImage(
+ LayerType type,
+ const scoped_refptr<TrackedCallback>& release_callback) {
+ if (!compositor_)
+ return PP_ERROR_BADRESOURCE;
+
+ if (compositor_->IsInProgress())
+ return PP_ERROR_INPROGRESS;
+
+ if (!SetType(type))
+ return PP_ERROR_BADARGUMENT;
+
+ // The layer's image has been set and it is not committed.
+ if (!release_callback_.is_null())
+ return PP_ERROR_INPROGRESS;
+
+ // Do not allow using a block callback as a release callback.
+ if (release_callback->is_blocking())
+ return PP_ERROR_BADARGUMENT;
+
+ return PP_OK;
}
} // namespace proxy
« no previous file with comments | « ppapi/proxy/compositor_layer_resource.h ('k') | ppapi/proxy/compositor_resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698