Index: content/common/gpu/media/gles2_external_texture_copier.cc |
diff --git a/content/common/gpu/media/gles2_external_texture_copier.cc b/content/common/gpu/media/gles2_external_texture_copier.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a3814d089ab33b6b35587a59ec6e09b8926bbe43 |
--- /dev/null |
+++ b/content/common/gpu/media/gles2_external_texture_copier.cc |
@@ -0,0 +1,112 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/common/gpu/media/gles2_external_texture_copier.h" |
+ |
+#include "base/logging.h" |
+ |
+namespace content { |
+ |
+static void CheckGlError(const char* op) { |
+#ifndef NDEBUG |
+ for (GLint error = glGetError(); error; error = glGetError()) { |
+ LOG(ERROR) << "after " << op <<" glError (0x" << std::hex << error << ")"; |
+ NOTREACHED(); |
+ } |
+#endif |
+} |
+ |
+Gles2ExternalTextureCopier::Gles2ExternalTextureCopier( |
+ int32 width, int32 height) |
+ : width_(width), |
greggman
2013/02/20 19:13:58
style nit: 4 spaces in front of :
dwkang1
2013/02/25 23:48:00
Done.
|
+ height_(height) { |
+ SaveState(); |
+ copier_.Initialize(); |
+ RestoreState(); |
+} |
+ |
+Gles2ExternalTextureCopier::~Gles2ExternalTextureCopier() { |
+ copier_.Destroy(); |
+} |
+ |
+bool Gles2ExternalTextureCopier::Copy( |
+ GLuint source_texture_id, GLuint destination_texture_id_) { |
+ SaveState(); |
+ glViewport(0, 0, width_, height_); |
+ copier_.DoCopyTexture( |
+ GL_TEXTURE_2D, source_texture_id, destination_texture_id_, 0, |
+ false, false, false, true); |
+ RestoreState(); |
+ return true; |
+} |
+ |
+void Gles2ExternalTextureCopier::SaveState() { |
+ // TODO(dwkang): Reportedly, glGetXXXs are extremely slow on some platforms. |
+ // Check if we can skip some of below or find out a way to get |
+ // the status from GLES2Decoder(). |
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previous_framebuffer_id_); |
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous_renderbuffer_id_); |
greggman
2013/02/20 19:13:58
render buffers are not used by copy
dwkang1
2013/02/25 23:48:00
Done.
|
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous_texture_2d_id_); |
greggman
2013/02/20 19:13:58
CopyTextureCHROMIUMResourceManager::DoCopyTexture
dwkang1
2013/02/25 23:48:00
Done.
|
+ glGetIntegerv(GL_CURRENT_PROGRAM, &previous_program_); |
+ glGetIntegerv(GL_VIEWPORT, previous_viewport_); |
+ glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vertex_array_buffer_binding_); |
+ glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &index_array_buffer_binding_); |
+ |
greggman
2013/02/20 19:13:58
You also need to query/restore GL_DEPTH_TEST, GL_S
dwkang1
2013/02/25 23:48:00
Done.
|
+ SaveStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib, 0); |
+ SaveStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib, 1); |
+ CheckGlError("SaveState"); |
greggman
2013/02/20 19:13:58
You also need to query and restore the Texture Par
dwkang1
2013/02/25 23:48:00
The doc says glTexParameter sets params for the ac
|
+} |
+ |
+void Gles2ExternalTextureCopier::RestoreState() { |
+ glBindFramebufferEXT(GL_FRAMEBUFFER, previous_framebuffer_id_); |
+ glBindRenderbufferEXT(GL_RENDERBUFFER, previous_renderbuffer_id_); |
+ glBindTexture(GL_TEXTURE_2D, previous_texture_2d_id_); |
+ glUseProgram(previous_program_); |
greggman
2013/02/20 19:13:58
Note: Querying and restoring bindings can never wo
dwkang1
2013/02/25 23:48:00
I added a TODO message for it.
|
+ glViewport(previous_viewport_[0], previous_viewport_[1], |
+ previous_viewport_[2], previous_viewport_[3]); |
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_array_buffer_binding_); |
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_buffer_binding_); |
+ |
+ RestoreStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib, 0); |
+ RestoreStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib, 1); |
+ CheckGlError("RestoreState"); |
+} |
+ |
+void Gles2ExternalTextureCopier::SaveStateForAttrib( |
+ GLuint attrib, int index) { |
+ glGetVertexAttribiv(attrib, GL_VERTEX_ATTRIB_ARRAY_ENABLED, |
+ &previous_vertex_attrib_[index].enabled); |
+ glGetVertexAttribiv(attrib, GL_VERTEX_ATTRIB_ARRAY_SIZE, |
+ &previous_vertex_attrib_[index].size); |
+ glGetVertexAttribiv(attrib, GL_VERTEX_ATTRIB_ARRAY_TYPE, |
+ &previous_vertex_attrib_[index].type); |
+ glGetVertexAttribiv(attrib, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, |
+ &previous_vertex_attrib_[index].normalized); |
+ glGetVertexAttribiv(attrib, GL_VERTEX_ATTRIB_ARRAY_STRIDE, |
+ &previous_vertex_attrib_[index].stride); |
+ glGetVertexAttribPointerv(attrib, GL_VERTEX_ATTRIB_ARRAY_POINTER, |
+ &previous_vertex_attrib_[index].pointer); |
+} |
+ |
+void Gles2ExternalTextureCopier::RestoreStateForAttrib( |
+ GLuint attrib, int index) { |
+ glVertexAttribPointer( |
+ attrib, |
+ previous_vertex_attrib_[index].size, |
+ previous_vertex_attrib_[index].type, |
+ previous_vertex_attrib_[index].normalized, |
+ previous_vertex_attrib_[index].stride, |
+ previous_vertex_attrib_[index].pointer); |
+ |
+ if (previous_vertex_attrib_[index].enabled) |
+ glEnableVertexAttribArray(attrib); |
+ else |
+ glDisableVertexAttribArray(attrib); |
+} |
+ |
+} // namespace content |