Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / stream_texture_android.cc
index 1d510e6..eb7f3bb 100644 (file)
@@ -9,9 +9,11 @@
 #include "content/common/gpu/gpu_channel.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "gpu/command_buffer/service/context_group.h"
+#include "gpu/command_buffer/service/context_state.h"
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "ui/gfx/size.h"
+#include "ui/gl/scoped_make_current.h"
 
 namespace content {
 
@@ -21,12 +23,10 @@ using gpu::gles2::TextureManager;
 using gpu::gles2::TextureRef;
 
 // static
-int32 StreamTexture::Create(
+bool StreamTexture::Create(
     GpuCommandBufferStub* owner_stub,
-    uint32 client_texture_id) {
-  GpuChannel* channel = owner_stub->channel();
-  int32 route_id = channel->GenerateRouteID();
-
+    uint32 client_texture_id,
+    int stream_id) {
   GLES2Decoder* decoder = owner_stub->decoder();
   TextureManager* texture_manager =
       decoder->GetContextGroup()->texture_manager();
@@ -38,7 +38,7 @@ int32 StreamTexture::Create(
     // TODO: Ideally a valid image id was returned to the client so that
     // it could then call glBindTexImage2D() for doing the following.
     scoped_refptr<gfx::GLImage> gl_image(
-        new StreamTexture(owner_stub, route_id, texture->service_id()));
+        new StreamTexture(owner_stub, stream_id, texture->service_id()));
     gfx::Size size = gl_image->GetSize();
     texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
     texture_manager->SetLevelInfo(texture,
@@ -53,19 +53,20 @@ int32 StreamTexture::Create(
                                   GL_UNSIGNED_BYTE,
                                   true);
     texture_manager->SetLevelImage(
-        texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image);
-    return route_id;
+        texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image.get());
+    return true;
   }
 
-  return 0;
+  return false;
 }
 
 StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
                              int32 route_id,
                              uint32 texture_id)
-    : surface_texture_(new gfx::SurfaceTexture(texture_id)),
+    : surface_texture_(gfx::SurfaceTexture::Create(texture_id)),
       size_(0, 0),
-      has_updated_(false),
+      has_valid_frame_(false),
+      has_pending_frame_(false),
       owner_stub_(owner_stub),
       route_id_(route_id),
       has_listener_(false),
@@ -73,6 +74,8 @@ StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
   owner_stub->AddDestructionObserver(this);
   memset(current_matrix_, 0, sizeof(current_matrix_));
   owner_stub->channel()->AddRoute(route_id, this);
+  surface_texture_->SetFrameAvailableCallback(base::Bind(
+      &StreamTexture::OnFrameAvailable, weak_factory_.GetWeakPtr()));
 }
 
 StreamTexture::~StreamTexture() {
@@ -92,27 +95,54 @@ void StreamTexture::OnWillDestroyStub() {
   surface_texture_ = NULL;
 }
 
-void StreamTexture::Destroy() {
+void StreamTexture::Destroy(bool have_context) {
   NOTREACHED();
 }
 
 void StreamTexture::WillUseTexImage() {
-  if (!owner_stub_)
+  if (!owner_stub_ || !surface_texture_.get())
     return;
 
-  // TODO(sievers): Update also when used in a different context.
-  //                Also see crbug.com/309162.
-  if (surface_texture_.get() &&
-      owner_stub_->decoder()->GetGLContext()->IsCurrent(NULL)) {
+  if (has_pending_frame_) {
+    scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current;
+    bool needs_make_current =
+        !owner_stub_->decoder()->GetGLContext()->IsCurrent(NULL);
+    // On Android we should not have to perform a real context switch here when
+    // using virtual contexts.
+    DCHECK(!needs_make_current || !owner_stub_->decoder()
+                                       ->GetContextGroup()
+                                       ->feature_info()
+                                       ->workarounds()
+                                       .use_virtualized_gl_contexts);
+    if (needs_make_current) {
+      scoped_make_current.reset(new ui::ScopedMakeCurrent(
+          owner_stub_->decoder()->GetGLContext(), owner_stub_->surface()));
+    }
     surface_texture_->UpdateTexImage();
+    has_valid_frame_ = true;
+    has_pending_frame_ = false;
+    if (scoped_make_current.get()) {
+      // UpdateTexImage() implies glBindTexture().
+      // The cmd decoder takes care of restoring the binding for this GLImage as
+      // far as the current context is concerned, but if we temporarily change
+      // it, we have to keep the state intact in *that* context also.
+      const gpu::gles2::ContextState* state =
+          owner_stub_->decoder()->GetContextState();
+      const gpu::gles2::TextureUnit& active_unit =
+          state->texture_units[state->active_texture_unit];
+      glBindTexture(GL_TEXTURE_EXTERNAL_OES,
+                    active_unit.bound_texture_external_oes.get()
+                        ? active_unit.bound_texture_external_oes->service_id()
+                        : 0);
+    }
   }
 
-  if (has_listener_) {
+  if (has_listener_ && has_valid_frame_) {
     float mtx[16];
     surface_texture_->GetTransformMatrix(mtx);
 
     // Only query the matrix once we have bound a valid frame.
-    if (has_updated_ && memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
+    if (memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
       memcpy(current_matrix_, mtx, sizeof(mtx));
 
       GpuStreamTextureMsg_MatrixChanged_Params params;
@@ -124,9 +154,8 @@ void StreamTexture::WillUseTexImage() {
 }
 
 void StreamTexture::OnFrameAvailable() {
-  has_updated_ = true;
-  DCHECK(has_listener_);
-  if (owner_stub_) {
+  has_pending_frame_ = true;
+  if (has_listener_ && owner_stub_) {
     owner_stub_->channel()->Send(
         new GpuStreamTextureMsg_FrameAvailable(route_id_));
   }
@@ -152,8 +181,6 @@ bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
 void StreamTexture::OnStartListening() {
   DCHECK(!has_listener_);
   has_listener_ = true;
-  surface_texture_->SetFrameAvailableCallback(base::Bind(
-      &StreamTexture::OnFrameAvailable, weak_factory_.GetWeakPtr()));
 }
 
 void StreamTexture::OnEstablishPeer(int32 primary_id, int32 secondary_id) {
@@ -166,4 +193,26 @@ void StreamTexture::OnEstablishPeer(int32 primary_id, int32 secondary_id) {
       process, surface_texture_, primary_id, secondary_id);
 }
 
+bool StreamTexture::BindTexImage(unsigned target) {
+  NOTREACHED();
+  return false;
+}
+
+void StreamTexture::ReleaseTexImage(unsigned target) {
+  NOTREACHED();
+}
+
+bool StreamTexture::CopyTexImage(unsigned target) {
+  return false;
+}
+
+bool StreamTexture::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
+                                         int z_order,
+                                         gfx::OverlayTransform transform,
+                                         const gfx::Rect& bounds_rect,
+                                         const gfx::RectF& crop_rect) {
+  NOTREACHED();
+  return false;
+}
+
 }  // namespace content