stream_texture_manager_android.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureAndroid::StreamTextureAndroid(
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannel* channel, int service_id)
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : surface_texture_bridge_(new gfx::SurfaceTextureBridge(service_id)),
19a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      size_(0, 0),
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_updated_(false),
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_(channel) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(current_matrix_, 0, sizeof(current_matrix_));
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureAndroid::~StreamTextureAndroid() {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::StreamTextureAndroid::Update() {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_texture_bridge_->UpdateTexImage();
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (matrix_callback_.is_null())
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float mtx[16];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_texture_bridge_->GetTransformMatrix(mtx);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only query the matrix once we have bound a valid frame.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_updated_ && memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(current_matrix_, mtx, sizeof(mtx));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuStreamTextureMsg_MatrixChanged_Params params;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&params.m00, mtx, sizeof(mtx));
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matrix_callback_.Run(params);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::StreamTextureAndroid::OnFrameAvailable(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_updated_ = true;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->Send(new GpuStreamTextureMsg_FrameAvailable(route_id));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)gfx::Size StreamTextureManagerAndroid::StreamTextureAndroid::GetSize() {
53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return size_;
54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::StreamTextureManagerAndroid(
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannel* channel)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : channel_(channel) {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StreamTextureManagerAndroid::~StreamTextureManagerAndroid() {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(textures_.size() == textures_from_service_id_.size());
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!textures_.IsEmpty())
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "Undestroyed surface textures while closing GPU channel.";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GLuint StreamTextureManagerAndroid::CreateStreamTexture(uint32 service_id,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        uint32 client_id) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // service_id: the actual GL texture name
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client_id: texture name given to the client in the renderer (unused here)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The return value here is what glCreateStreamTextureCHROMIUM() will return
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to identify the stream (i.e. surface texture).
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* texture = new StreamTextureAndroid(
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      channel_, service_id);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  textures_from_service_id_.AddWithID(texture, service_id);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return textures_.Add(texture);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::DestroyStreamTexture(uint32 service_id) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::StreamTexture* texture = textures_from_service_id_.Lookup(service_id);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (texture) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    textures_from_service_id_.Remove(service_id);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (TextureMap::Iterator<StreamTextureAndroid> it(&textures_);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !it.IsAtEnd(); it.Advance()) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (it.GetCurrentValue() == texture) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        textures_.Remove(it.GetCurrentKey());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::StreamTexture* StreamTextureManagerAndroid::LookupStreamTexture(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 service_id) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return textures_from_service_id_.Lookup(service_id);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::SendMatrixChanged(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int route_id,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GpuStreamTextureMsg_MatrixChanged_Params& params) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  channel_->Send(new GpuStreamTextureMsg_MatrixChanged(route_id, params));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::RegisterStreamTextureProxy(
106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int32 stream_id, int32 route_id) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream_texture) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(sievers): Post from binder thread to IO thread directly.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Closure frame_cb = base::Bind(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &StreamTextureAndroid::OnFrameAvailable,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          stream_texture->AsWeakPtr(),
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          route_id);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StreamTextureAndroid::MatrixChangedCB matrix_cb = base::Bind(
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &StreamTextureManagerAndroid::SendMatrixChanged,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Unretained(this),
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          route_id);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stream_texture->set_matrix_changed_callback(matrix_cb);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stream_texture->surface_texture_bridge()->SetFrameAvailableCallback(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        frame_cb);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void StreamTextureManagerAndroid::EstablishStreamTexture(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32 stream_id, int32 primary_id, int32 secondary_id) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process = channel_->renderer_pid();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (stream_texture) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        process,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        stream_texture->surface_texture_bridge(),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        primary_id,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        secondary_id);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid StreamTextureManagerAndroid::SetStreamTextureSize(
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    int32 stream_id, const gfx::Size& size) {
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (stream_texture)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    stream_texture->SetSize(size);
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
146