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

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2443023002: gpu: Add CHROMIUM_copy_image extension.
Patch Set: rebase Created 4 years, 2 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
Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 40f5c63f5eacf92a34f0ad249c536f857c99e617..0c5b0aeb23ea1269b19b16666c93b082f64f0fd9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1038,6 +1038,16 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
void DoBindTexImage2DCHROMIUM(GLenum target, GLint image_id, GLint fence_id);
void DoReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id);
+ void DoCopyImageSubDataCHROMIUM(GLint source_image_id,
+ GLint dest_texture_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint in_fence_id,
+ GLint out_fence_id);
void DoTraceEndCHROMIUM(void);
@@ -16934,6 +16944,152 @@ void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(GLenum target,
Texture::UNBOUND);
}
+void GLES2DecoderImpl::DoCopyImageSubDataCHROMIUM(GLint source_image_id,
+ GLint dest_texture_id,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint in_fence_id,
+ GLint out_fence_id) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyImageSubDataCHROMIUM");
+
+ TextureRef* dest_texture_ref = GetTexture(dest_texture_id);
+ Texture* dest_texture = dest_texture_ref->texture();
+ GLenum dest_target = dest_texture->target();
+ GLenum dest_type = 0;
+ GLenum dest_internal_format = 0;
+ bool dest_level_defined = dest_texture->GetLevelType(
+ dest_target, 0, &dest_type, &dest_internal_format);
+ if (!dest_level_defined) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "destination texture is not defined");
+ return;
+ }
+ if (dest_target != GL_TEXTURE_2D) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyImageSubDataCHROMIUM",
+ "destination texture bad target.");
+ return;
+ }
+ if (!dest_texture->ValidForTexture(dest_target, 0, xoffset, yoffset, 0, width,
+ height, 1)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCopyImageSubDataCHROMIUM",
+ "destination texture bad dimensions.");
+ return;
+ }
+ int dest_width = 0;
+ int dest_height = 0;
+ bool ok = dest_texture->GetLevelSize(dest_target, 0, &dest_width,
+ &dest_height, nullptr);
+ DCHECK(ok);
+ if (xoffset != 0 || yoffset != 0 || width != dest_width ||
+ height != dest_height) {
+ gfx::Rect cleared_rect;
+ if (TextureManager::CombineAdjacentRects(
+ dest_texture->GetLevelClearedRect(dest_target, 0),
+ gfx::Rect(xoffset, yoffset, width, height), &cleared_rect)) {
+ DCHECK_GE(
+ cleared_rect.size().GetArea(),
+ dest_texture->GetLevelClearedRect(dest_target, 0).size().GetArea());
+ texture_manager()->SetLevelClearedRect(dest_texture_ref, dest_target, 0,
+ cleared_rect);
+ } else {
+ // Otherwise clear part of texture level that is not already cleared.
+ if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref,
+ dest_target, 0)) {
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyImageSubDataCHROMIUM",
+ "destination texture dimensions too big");
+ return;
+ }
+ }
+ } else {
+ texture_manager()->SetLevelCleared(dest_texture_ref, dest_target, 0, true);
+ }
+
+ gl::GLImage* image = image_manager()->LookupImage(source_image_id);
+ if (!image) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "no image found with the given ID");
+ return;
+ }
+
+ gl::GLFence* in_fence = nullptr;
+ if (in_fence_id) {
+ in_fence = fence_manager()->LookupFence(in_fence_id);
+ if (!in_fence) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "no fence found with the given ID");
+ return;
+ }
+ }
+
+ gl::GLFence* out_fence = nullptr;
+ if (out_fence_id) {
+ out_fence = fence_manager()->LookupFence(out_fence_id);
+ if (!out_fence) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "no fence found with the given ID");
+ return;
+ }
+ }
+
+ if (image->CopySubImageData(
+ dest_texture->service_id(), gfx::Point(xoffset, yoffset),
+ gfx::Rect(x, y, width, height), in_fence, out_fence)) {
+ return;
+ }
+
+ if (!InitializeCopyTextureCHROMIUM("glCopyImageSubDataCHROMIUM"))
+ return;
+
+ // Output fence must have support for client side signaling.
+ if (out_fence && !out_fence->SignalSupported()) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "bad output fence");
+ return;
+ }
+
+ if (!features().oes_egl_image_external) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "oes_egl_image_external missing");
+ return;
+ }
+
+ GLuint temp_texture = 0;
+ glGenTextures(1, &temp_texture);
+ ScopedTextureBinder binder(&state_, temp_texture, GL_TEXTURE_EXTERNAL_OES);
+
+ if (!image->BindTexImage(GL_TEXTURE_EXTERNAL_OES, in_fence)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glCopyImageSubDataCHROMIUM",
+ "BindTexImage failed");
+ glDeleteTextures(1, &temp_texture);
+ return;
+ }
+
+ gfx::Size image_size = image->GetSize();
+ copy_texture_CHROMIUM_->DoCopySubTexture(
+ this, GL_TEXTURE_EXTERNAL_OES, temp_texture, image->GetInternalFormat(),
+ dest_target, dest_texture->service_id(), dest_internal_format, xoffset,
+ yoffset, x, y, width, height, dest_width, dest_height, image_size.width(),
+ image_size.height(), false, false, false);
+
+ glDeleteTextures(1, &temp_texture);
+
+ if (out_fence) {
+ gl::GLSurface* surface = gl::GLSurface::GetCurrent();
+ if (surface->SupportsInsertFence()) {
+ // Insert fence and forward signal to |out_fence|.
+ surface->InsertFence(base::Bind(&gl::GLFence::Signal, out_fence));
+ } else {
+ LOG(WARNING) << "Fence support missing, using glFinish()";
+ glFinish();
+ out_fence->Signal();
+ }
+ }
+}
+
error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
uint32_t immediate_data_size,
const volatile void* cmd_data) {
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_ids_autogen.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698