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.
5 #include "content/common/gpu/stream_texture_android.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"
18 using gpu::gles2::ContextGroup;
19 using gpu::gles2::GLES2Decoder;
20 using gpu::gles2::TextureManager;
21 using gpu::gles2::TextureRef;
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();
30 GLES2Decoder* decoder = owner_stub->decoder();
31 TextureManager* texture_manager =
32 decoder->GetContextGroup()->texture_manager();
33 TextureRef* texture = texture_manager->GetTexture(client_texture_id);
35 if (texture && (!texture->texture()->target() ||
36 texture->texture()->target() == GL_TEXTURE_EXTERNAL_OES)) {
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,
55 texture_manager->SetLevelImage(
56 texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image);
63 StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
66 : surface_texture_(new gfx::SurfaceTexture(texture_id)),
69 owner_stub_(owner_stub),
73 owner_stub->AddDestructionObserver(this);
74 memset(current_matrix_, 0, sizeof(current_matrix_));
75 owner_stub->channel()->AddRoute(route_id, this);
78 StreamTexture::~StreamTexture() {
80 owner_stub_->RemoveDestructionObserver(this);
81 owner_stub_->channel()->RemoveRoute(route_id_);
85 void StreamTexture::OnWillDestroyStub() {
86 owner_stub_->RemoveDestructionObserver(this);
87 owner_stub_->channel()->RemoveRoute(route_id_);
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;
95 void StreamTexture::Destroy() {
99 void StreamTexture::WillUseTexImage() {
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();
112 surface_texture_->GetTransformMatrix(mtx);
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));
118 GpuStreamTextureMsg_MatrixChanged_Params params;
119 memcpy(¶ms.m00, mtx, sizeof(mtx));
120 owner_stub_->channel()->Send(
121 new GpuStreamTextureMsg_MatrixChanged(route_id_, params));
126 void StreamTexture::OnFrameAvailable() {
128 DCHECK(has_listener_);
130 owner_stub_->channel()->Send(
131 new GpuStreamTextureMsg_FrameAvailable(route_id_));
135 gfx::Size StreamTexture::GetSize() {
139 bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
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()
152 void StreamTexture::OnStartListening() {
153 DCHECK(!has_listener_);
154 has_listener_ = true;
155 surface_texture_->SetFrameAvailableCallback(base::Bind(
156 &StreamTexture::OnFrameAvailable, weak_factory_.GetWeakPtr()));
159 void StreamTexture::OnEstablishPeer(int32 primary_id, int32 secondary_id) {
163 base::ProcessHandle process = owner_stub_->channel()->renderer_pid();
165 SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
166 process, surface_texture_, primary_id, secondary_id);
169 } // namespace content