Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / stream_texture_android.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/common/gpu/stream_texture_android.h"
6
7 #include "base/bind.h"
8 #include "content/common/android/surface_texture_peer.h"
9 #include "content/common/gpu/gpu_channel.h"
10 #include "content/common/gpu/gpu_messages.h"
11 #include "gpu/command_buffer/service/context_group.h"
12 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
13 #include "gpu/command_buffer/service/texture_manager.h"
14 #include "ui/gfx/size.h"
15
16 namespace content {
17
18 using gpu::gles2::ContextGroup;
19 using gpu::gles2::GLES2Decoder;
20 using gpu::gles2::TextureManager;
21 using gpu::gles2::TextureRef;
22
23 // static
24 int32 StreamTexture::Create(
25     GpuCommandBufferStub* owner_stub,
26     uint32 client_texture_id) {
27   GpuChannel* channel = owner_stub->channel();
28   int32 route_id = channel->GenerateRouteID();
29
30   GLES2Decoder* decoder = owner_stub->decoder();
31   TextureManager* texture_manager =
32       decoder->GetContextGroup()->texture_manager();
33   TextureRef* texture = texture_manager->GetTexture(client_texture_id);
34
35   if (texture && (!texture->texture()->target() ||
36                   texture->texture()->target() == GL_TEXTURE_EXTERNAL_OES)) {
37
38     // TODO: Ideally a valid image id was returned to the client so that
39     // it could then call glBindTexImage2D() for doing the following.
40     scoped_refptr<gfx::GLImage> gl_image(
41         new StreamTexture(owner_stub, route_id, texture->service_id()));
42     gfx::Size size = gl_image->GetSize();
43     texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
44     texture_manager->SetLevelInfo(texture,
45                                   GL_TEXTURE_EXTERNAL_OES,
46                                   0,
47                                   GL_RGBA,
48                                   size.width(),
49                                   size.height(),
50                                   1,
51                                   0,
52                                   GL_RGBA,
53                                   GL_UNSIGNED_BYTE,
54                                   true);
55     texture_manager->SetLevelImage(
56         texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image);
57     return route_id;
58   }
59
60   return 0;
61 }
62
63 StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
64                              int32 route_id,
65                              uint32 texture_id)
66     : surface_texture_(new gfx::SurfaceTexture(texture_id)),
67       size_(0, 0),
68       has_updated_(false),
69       owner_stub_(owner_stub),
70       route_id_(route_id),
71       has_listener_(false),
72       weak_factory_(this) {
73   owner_stub->AddDestructionObserver(this);
74   memset(current_matrix_, 0, sizeof(current_matrix_));
75   owner_stub->channel()->AddRoute(route_id, this);
76 }
77
78 StreamTexture::~StreamTexture() {
79   if (owner_stub_) {
80     owner_stub_->RemoveDestructionObserver(this);
81     owner_stub_->channel()->RemoveRoute(route_id_);
82   }
83 }
84
85 void StreamTexture::OnWillDestroyStub() {
86   owner_stub_->RemoveDestructionObserver(this);
87   owner_stub_->channel()->RemoveRoute(route_id_);
88   owner_stub_ = NULL;
89
90   // If the owner goes away, there is no need to keep the SurfaceTexture around.
91   // The GL texture will keep working regardless with the currently bound frame.
92   surface_texture_ = NULL;
93 }
94
95 void StreamTexture::Destroy() {
96   NOTREACHED();
97 }
98
99 void StreamTexture::WillUseTexImage() {
100   if (!owner_stub_)
101     return;
102
103   // TODO(sievers): Update also when used in a different context.
104   //                Also see crbug.com/309162.
105   if (surface_texture_.get() &&
106       owner_stub_->decoder()->GetGLContext()->IsCurrent(NULL)) {
107     surface_texture_->UpdateTexImage();
108   }
109
110   if (has_listener_) {
111     float mtx[16];
112     surface_texture_->GetTransformMatrix(mtx);
113
114     // Only query the matrix once we have bound a valid frame.
115     if (has_updated_ && memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
116       memcpy(current_matrix_, mtx, sizeof(mtx));
117
118       GpuStreamTextureMsg_MatrixChanged_Params params;
119       memcpy(&params.m00, mtx, sizeof(mtx));
120       owner_stub_->channel()->Send(
121           new GpuStreamTextureMsg_MatrixChanged(route_id_, params));
122     }
123   }
124 }
125
126 void StreamTexture::OnFrameAvailable() {
127   has_updated_ = true;
128   DCHECK(has_listener_);
129   if (owner_stub_) {
130     owner_stub_->channel()->Send(
131         new GpuStreamTextureMsg_FrameAvailable(route_id_));
132   }
133 }
134
135 gfx::Size StreamTexture::GetSize() {
136   return size_;
137 }
138
139 bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
140   bool handled = true;
141   IPC_BEGIN_MESSAGE_MAP(StreamTexture, message)
142     IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_StartListening, OnStartListening)
143     IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_EstablishPeer, OnEstablishPeer)
144     IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_SetSize, OnSetSize)
145     IPC_MESSAGE_UNHANDLED(handled = false)
146   IPC_END_MESSAGE_MAP()
147
148   DCHECK(handled);
149   return handled;
150 }
151
152 void StreamTexture::OnStartListening() {
153   DCHECK(!has_listener_);
154   has_listener_ = true;
155   surface_texture_->SetFrameAvailableCallback(base::Bind(
156       &StreamTexture::OnFrameAvailable, weak_factory_.GetWeakPtr()));
157 }
158
159 void StreamTexture::OnEstablishPeer(int32 primary_id, int32 secondary_id) {
160   if (!owner_stub_)
161     return;
162
163   base::ProcessHandle process = owner_stub_->channel()->renderer_pid();
164
165   SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
166       process, surface_texture_, primary_id, secondary_id);
167 }
168
169 }  // namespace content