15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/stream_texture_manager_android.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/stream_texture.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/gl/android/surface_texture_bridge.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gl/gl_bindings.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureAndroid::StreamTextureAndroid(
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannel* channel, int service_id)
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : surface_texture_bridge_(new gfx::SurfaceTextureBridge(service_id)),
20a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      size_(0, 0),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_updated_(false),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_(channel) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(current_matrix_, 0, sizeof(current_matrix_));
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureAndroid::~StreamTextureAndroid() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::StreamTextureAndroid::Update() {
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GLint texture_id = 0;
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &texture_id);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_texture_bridge_->UpdateTexImage();
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (matrix_callback_.is_null())
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float mtx[16];
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_texture_bridge_->GetTransformMatrix(mtx);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only query the matrix once we have bound a valid frame.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_updated_ && memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(current_matrix_, mtx, sizeof(mtx));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuStreamTextureMsg_MatrixChanged_Params params;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&params.m00, mtx, sizeof(mtx));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matrix_callback_.Run(params);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::StreamTextureAndroid::OnFrameAvailable(
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_updated_ = true;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->Send(new GpuStreamTextureMsg_FrameAvailable(route_id));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)gfx::Size StreamTextureManagerAndroid::StreamTextureAndroid::GetSize() {
57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return size_;
58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureManagerAndroid(
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannel* channel)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : channel_(channel) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::~StreamTextureManagerAndroid() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(textures_.size() == textures_from_service_id_.size());
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!textures_.IsEmpty())
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Undestroyed surface textures while closing GPU channel.";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLuint StreamTextureManagerAndroid::CreateStreamTexture(uint32 service_id,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        uint32 client_id) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // service_id: the actual GL texture name
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client_id: texture name given to the client in the renderer (unused here)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The return value here is what glCreateStreamTextureCHROMIUM() will return
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to identify the stream (i.e. surface texture).
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* texture = new StreamTextureAndroid(
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_, service_id);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textures_from_service_id_.AddWithID(texture, service_id);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return textures_.Add(texture);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::DestroyStreamTexture(uint32 service_id) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::StreamTexture* texture = textures_from_service_id_.Lookup(service_id);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (texture) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    textures_from_service_id_.Remove(service_id);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (TextureMap::Iterator<StreamTextureAndroid> it(&textures_);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !it.IsAtEnd(); it.Advance()) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it.GetCurrentValue() == texture) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        textures_.Remove(it.GetCurrentKey());
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::StreamTexture* StreamTextureManagerAndroid::LookupStreamTexture(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 service_id) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return textures_from_service_id_.Lookup(service_id);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::SendMatrixChanged(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuStreamTextureMsg_MatrixChanged_Params& params) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->Send(new GpuStreamTextureMsg_MatrixChanged(route_id, params));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::RegisterStreamTextureProxy(
110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int32 stream_id, int32 route_id) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream_texture) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(sievers): Post from binder thread to IO thread directly.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure frame_cb = base::Bind(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &StreamTextureAndroid::OnFrameAvailable,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          stream_texture->AsWeakPtr(),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          route_id);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamTextureAndroid::MatrixChangedCB matrix_cb = base::Bind(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &StreamTextureManagerAndroid::SendMatrixChanged,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          route_id);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stream_texture->set_matrix_changed_callback(matrix_cb);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stream_texture->surface_texture_bridge()->SetFrameAvailableCallback(
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frame_cb);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::EstablishStreamTexture(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32 stream_id, int32 primary_id, int32 secondary_id) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = channel_->renderer_pid();
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream_texture) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        stream_texture->surface_texture_bridge(),
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        primary_id,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        secondary_id);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid StreamTextureManagerAndroid::SetStreamTextureSize(
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int32 stream_id, const gfx::Size& size) {
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (stream_texture)
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    stream_texture->SetSize(size);
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
150