Skip to content

Commit

Permalink
[gpu] Remove StreamTexture(Manager) concept from command decoder
Browse files Browse the repository at this point in the history
Instead add a simple GpuControl interface to attach a GLImage-wrapped
 SurfaceTexture ref to a texture which will provide the
 necessary hooks.

BUG=282700,309162
R=palmer@chromium.org, piman@chromium.org, reveman@chromium.org

Review URL: https://codereview.chromium.org/147463002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247334 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
sievers@google.com committed Jan 27, 2014
1 parent dc6938a commit 7bffe9e
Show file tree
Hide file tree
Showing 67 changed files with 592 additions and 1,424 deletions.
10 changes: 10 additions & 0 deletions content/common/gpu/client/command_buffer_proxy_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,16 @@ void CommandBufferProxyImpl::Echo(const base::Closure& callback) {
echo_tasks_.push(callback);
}

uint32 CommandBufferProxyImpl::CreateStreamTexture(uint32 texture_id) {
if (last_state_.error != gpu::error::kNoError)
return 0;

int32 stream_id = 0;
Send(new GpuCommandBufferMsg_CreateStreamTexture(
route_id_, texture_id, &stream_id));
return stream_id;
}

uint32 CommandBufferProxyImpl::InsertSyncPoint() {
if (last_state_.error != gpu::error::kNoError)
return 0;
Expand Down
1 change: 1 addition & 0 deletions content/common/gpu/client/command_buffer_proxy_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class CommandBufferProxyImpl
virtual void SendManagedMemoryStats(const gpu::ManagedMemoryStats& stats)
OVERRIDE;
virtual void Echo(const base::Closure& callback) OVERRIDE;
virtual uint32 CreateStreamTexture(uint32 texture_id) OVERRIDE;

int GetRouteID() const;
bool ProduceFrontBuffer(const gpu::Mailbox& mailbox);
Expand Down
7 changes: 0 additions & 7 deletions content/common/gpu/gpu_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@
#include "ipc/ipc_channel_posix.h"
#endif

#if defined(OS_ANDROID)
#include "content/common/gpu/stream_texture_manager_android.h"
#endif

namespace content {
namespace {

Expand Down Expand Up @@ -458,9 +454,6 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
disallowed_features_.multisampling =
command_line->HasSwitch(switches::kDisableGLMultisampling);
#if defined(OS_ANDROID)
stream_texture_manager_.reset(new StreamTextureManagerAndroid(this));
#endif
}


Expand Down
15 changes: 0 additions & 15 deletions content/common/gpu/gpu_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ class ImageManager;
}
}

#if defined(OS_ANDROID)
namespace content {
class StreamTextureManagerAndroid;
}
#endif

namespace content {
class DevToolsGpuAgent;
class GpuChannelManager;
Expand Down Expand Up @@ -149,12 +143,6 @@ class GpuChannel : public IPC::Listener,
void SetPreemptByFlag(
scoped_refptr<gpu::PreemptionFlag> preemption_flag);

#if defined(OS_ANDROID)
StreamTextureManagerAndroid* stream_texture_manager() {
return stream_texture_manager_.get();
}
#endif

void CacheShader(const std::string& key, const std::string& shader);

void AddFilter(IPC::ChannelProxy::MessageFilter* filter);
Expand Down Expand Up @@ -225,9 +213,6 @@ class GpuChannel : public IPC::Listener,

scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_;
scoped_refptr<gpu::gles2::ImageManager> image_manager_;
#if defined(OS_ANDROID)
scoped_ptr<StreamTextureManagerAndroid> stream_texture_manager_;
#endif

typedef IDMap<GpuCommandBufferStub, IDMapOwnPointer> StubMap;
StubMap stubs_;
Expand Down
18 changes: 12 additions & 6 deletions content/common/gpu/gpu_command_buffer_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#endif

#if defined(OS_ANDROID)
#include "content/common/gpu/stream_texture_manager_android.h"
#include "content/common/gpu/stream_texture_android.h"
#endif

namespace content {
Expand Down Expand Up @@ -141,15 +141,10 @@ GpuCommandBufferStub::GpuCommandBufferStub(
if (share_group) {
context_group_ = share_group->context_group_;
} else {
gpu::StreamTextureManager* stream_texture_manager = NULL;
#if defined(OS_ANDROID)
stream_texture_manager = channel_->stream_texture_manager();
#endif
context_group_ = new gpu::gles2::ContextGroup(
mailbox_manager,
image_manager,
new GpuCommandBufferMemoryTracker(channel),
stream_texture_manager,
NULL,
true);
}
Expand Down Expand Up @@ -228,6 +223,8 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
OnRegisterGpuMemoryBuffer);
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyGpuMemoryBuffer,
OnDestroyGpuMemoryBuffer);
IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture,
OnCreateStreamTexture)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()

Expand Down Expand Up @@ -575,6 +572,15 @@ void GpuCommandBufferStub::OnSetLatencyInfo(
latency_info_callback_.Run(latency_info);
}

void GpuCommandBufferStub::OnCreateStreamTexture(uint32 texture_id,
int32* stream_id) {
#if defined(OS_ANDROID)
*stream_id = StreamTexture::Create(this, texture_id);
#else
*stream_id = 0;
#endif
}

void GpuCommandBufferStub::SetLatencyInfoCallback(
const LatencyInfoCallback& callback) {
latency_info_callback_ = callback;
Expand Down
1 change: 1 addition & 0 deletions content/common/gpu/gpu_command_buffer_stub.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class GpuCommandBufferStub
void OnCommandProcessed();
void OnParseError();
void OnSetLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info);
void OnCreateStreamTexture(uint32 texture_id, int32* stream_id);

void ReportState();

Expand Down
5 changes: 5 additions & 0 deletions content/common/gpu/gpu_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,11 @@ IPC_MESSAGE_ROUTED5(GpuCommandBufferMsg_RegisterGpuMemoryBuffer,
IPC_MESSAGE_ROUTED1(GpuCommandBufferMsg_DestroyGpuMemoryBuffer,
int32 /* id */)

// Attaches an external image stream to the client texture.
IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_CreateStreamTexture,
uint32, /* client_texture_id */
int32 /* stream_id */)

//------------------------------------------------------------------------------
// Accelerated Video Decoder Messages
// These messages are sent from Renderer process to GPU process.
Expand Down
169 changes: 169 additions & 0 deletions content/common/gpu/stream_texture_android.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/common/gpu/stream_texture_android.h"

#include "base/bind.h"
#include "content/common/android/surface_texture_peer.h"
#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/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gfx/size.h"

namespace content {

using gpu::gles2::ContextGroup;
using gpu::gles2::GLES2Decoder;
using gpu::gles2::TextureManager;
using gpu::gles2::TextureRef;

// static
int32 StreamTexture::Create(
GpuCommandBufferStub* owner_stub,
uint32 client_texture_id) {
GpuChannel* channel = owner_stub->channel();
int32 route_id = channel->GenerateRouteID();

GLES2Decoder* decoder = owner_stub->decoder();
TextureManager* texture_manager =
decoder->GetContextGroup()->texture_manager();
TextureRef* texture = texture_manager->GetTexture(client_texture_id);

if (texture && (!texture->texture()->target() ||
texture->texture()->target() == GL_TEXTURE_EXTERNAL_OES)) {

// 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()));
gfx::Size size = gl_image->GetSize();
texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
texture_manager->SetLevelInfo(texture,
GL_TEXTURE_EXTERNAL_OES,
0,
GL_RGBA,
size.width(),
size.height(),
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
true);
texture_manager->SetLevelImage(
texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image);
return route_id;
}

return 0;
}

StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
int32 route_id,
uint32 texture_id)
: surface_texture_(new gfx::SurfaceTexture(texture_id)),
size_(0, 0),
has_updated_(false),
owner_stub_(owner_stub),
route_id_(route_id),
has_listener_(false),
weak_factory_(this) {
owner_stub->AddDestructionObserver(this);
memset(current_matrix_, 0, sizeof(current_matrix_));
owner_stub->channel()->AddRoute(route_id, this);
}

StreamTexture::~StreamTexture() {
if (owner_stub_) {
owner_stub_->RemoveDestructionObserver(this);
owner_stub_->channel()->RemoveRoute(route_id_);
}
}

void StreamTexture::OnWillDestroyStub() {
owner_stub_->RemoveDestructionObserver(this);
owner_stub_->channel()->RemoveRoute(route_id_);
owner_stub_ = NULL;

// If the owner goes away, there is no need to keep the SurfaceTexture around.
// The GL texture will keep working regardless with the currently bound frame.
surface_texture_ = NULL;
}

void StreamTexture::Destroy() {
NOTREACHED();
}

void StreamTexture::WillUseTexImage() {
if (!owner_stub_)
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)) {
surface_texture_->UpdateTexImage();
}

if (has_listener_) {
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) {
memcpy(current_matrix_, mtx, sizeof(mtx));

GpuStreamTextureMsg_MatrixChanged_Params params;
memcpy(&params.m00, mtx, sizeof(mtx));
owner_stub_->channel()->Send(
new GpuStreamTextureMsg_MatrixChanged(route_id_, params));
}
}
}

void StreamTexture::OnFrameAvailable() {
has_updated_ = true;
DCHECK(has_listener_);
if (owner_stub_) {
owner_stub_->channel()->Send(
new GpuStreamTextureMsg_FrameAvailable(route_id_));
}
}

gfx::Size StreamTexture::GetSize() {
return size_;
}

bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(StreamTexture, message)
IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_StartListening, OnStartListening)
IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_EstablishPeer, OnEstablishPeer)
IPC_MESSAGE_HANDLER(GpuStreamTextureMsg_SetSize, OnSetSize)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()

DCHECK(handled);
return handled;
}

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) {
if (!owner_stub_)
return;

base::ProcessHandle process = owner_stub_->channel()->renderer_pid();

SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
process, surface_texture_, primary_id, secondary_id);
}

} // namespace content
75 changes: 75 additions & 0 deletions content/common/gpu/stream_texture_android.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_
#define CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_

#include "base/basictypes.h"
#include "base/memory/weak_ptr.h"
#include "content/common/gpu/gpu_command_buffer_stub.h"
#include "ipc/ipc_listener.h"
#include "ui/gl/android/surface_texture.h"
#include "ui/gl/gl_image.h"

namespace gfx {
class Size;
}

namespace content {

class StreamTexture : public gfx::GLImage,
public IPC::Listener,
public GpuCommandBufferStub::DestructionObserver {
public:
static int32 Create(GpuCommandBufferStub* owner_stub,
uint32 client_texture_id);

private:
StreamTexture(GpuCommandBufferStub* owner_stub,
int32 route_id,
uint32 texture_id);
virtual ~StreamTexture();

// gfx::GLImage implementation:
virtual void Destroy() OVERRIDE;
virtual gfx::Size GetSize() OVERRIDE;
virtual void WillUseTexImage() OVERRIDE;
virtual void DidUseTexImage() OVERRIDE {}

// GpuCommandBufferStub::DestructionObserver implementation.
virtual void OnWillDestroyStub() OVERRIDE;

// Called when a new frame is available for the SurfaceTexture.
void OnFrameAvailable();

// IPC::Listener implementation:
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;

// IPC message handlers:
void OnStartListening();
void OnEstablishPeer(int32 primary_id, int32 secondary_id);
void OnSetSize(const gfx::Size& size) { size_ = size; }

scoped_refptr<gfx::SurfaceTexture> surface_texture_;

// Current transform matrix of the surface texture.
float current_matrix_[16];

// Current size of the surface texture.
gfx::Size size_;

// Whether the surface texture has been updated.
bool has_updated_;

GpuCommandBufferStub* owner_stub_;
int32 route_id_;
bool has_listener_;

base::WeakPtrFactory<StreamTexture> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(StreamTexture);
};

} // namespace content

#endif // CONTENT_COMMON_GPU_STREAM_TEXTURE_ANDROID_H_
Loading

0 comments on commit 7bffe9e

Please sign in to comment.