| Index: content/common/gpu/stream_texture_android.cc
|
| diff --git a/content/common/gpu/stream_texture_android.cc b/content/common/gpu/stream_texture_android.cc
|
| index 84a0d1fa64223664b8c9fb6e41e062820ee38e1b..158430f44973fe664f24d101dde9310105e5a8e5 100644
|
| --- a/content/common/gpu/stream_texture_android.cc
|
| +++ b/content/common/gpu/stream_texture_android.cc
|
| @@ -12,8 +12,11 @@
|
| #include "gpu/command_buffer/service/context_state.h"
|
| #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
|
| #include "gpu/command_buffer/service/texture_manager.h"
|
| +#include "ipc/ipc_listener.h"
|
| #include "ui/gfx/geometry/size.h"
|
| +#include "ui/gl/android/surface_texture.h"
|
| #include "ui/gl/gl_context.h"
|
| +#include "ui/gl/gl_image.h"
|
| #include "ui/gl/scoped_make_current.h"
|
|
|
| namespace content {
|
| @@ -23,11 +26,110 @@ using gpu::gles2::GLES2Decoder;
|
| using gpu::gles2::TextureManager;
|
| using gpu::gles2::TextureRef;
|
|
|
| +class StreamTexture : public gl::GLImage,
|
| + public IPC::Listener,
|
| + public GpuCommandBufferStub::DestructionObserver {
|
| + public:
|
| + static scoped_refptr<StreamTexture> Create(GpuCommandBufferStub* owner_stub,
|
| + uint32 client_texture_id,
|
| + int32 stream_id);
|
| +
|
| + void SetReleaseCallback(const base::Closure& release_callback) {
|
| + release_callback_ = release_callback;
|
| + }
|
| + void SetSize(GpuCommandBufferStub* owner_stub,
|
| + uint32 client_texture_id,
|
| + size_t width,
|
| + size_t height) {
|
| + size_.SetSize(width, height);
|
| +
|
| + 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)) {
|
| + return;
|
| + }
|
| +
|
| + // Prevent deletion on SetLevelInfo()
|
| + scoped_refptr<StreamTexture> gl_image = this;
|
| + texture_manager->SetLevelInfo(
|
| + texture, GL_TEXTURE_EXTERNAL_OES, 0, GetInternalFormat(), width, height,
|
| + 1, 0, GetInternalFormat(), GL_UNSIGNED_BYTE, gfx::Rect(size_));
|
| + texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0,
|
| + gl_image.get(),
|
| + gpu::gles2::Texture::UNBOUND);
|
| + }
|
| +
|
| + private:
|
| + StreamTexture(GpuCommandBufferStub* owner_stub,
|
| + int32 route_id,
|
| + uint32 texture_id);
|
| + ~StreamTexture() override;
|
| +
|
| + // gl::GLImage implementation:
|
| + void Destroy(bool have_context) override;
|
| + gfx::Size GetSize() override;
|
| + unsigned GetInternalFormat() override;
|
| + bool BindTexImage(unsigned target) override;
|
| + void ReleaseTexImage(unsigned target) override;
|
| + bool CopyTexImage(unsigned target) override;
|
| + bool CopyTexSubImage(unsigned target,
|
| + const gfx::Point& offset,
|
| + const gfx::Rect& rect) override;
|
| + bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
|
| + int z_order,
|
| + gfx::OverlayTransform transform,
|
| + const gfx::Rect& bounds_rect,
|
| + const gfx::RectF& crop_rect) override;
|
| + void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
|
| + uint64_t process_tracing_id,
|
| + const std::string& dump_name) override;
|
| +
|
| + // GpuCommandBufferStub::DestructionObserver implementation.
|
| + void OnWillDestroyStub() override;
|
| +
|
| + // Called when a new frame is available for the SurfaceTexture.
|
| + void OnFrameAvailable();
|
| +
|
| + // IPC::Listener implementation:
|
| + bool OnMessageReceived(const IPC::Message& message) override;
|
| +
|
| + // IPC message handlers:
|
| + void OnStartListening();
|
| + void OnEstablishPeer(int32 primary_id, int32 secondary_id);
|
| +
|
| + 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 we ever bound a valid frame.
|
| + bool has_valid_frame_;
|
| +
|
| + // Whether a new frame is available that we should update to.
|
| + bool has_pending_frame_;
|
| +
|
| + GpuCommandBufferStub* owner_stub_;
|
| + int32 route_id_;
|
| + bool has_listener_;
|
| + uint32 texture_id_;
|
| +
|
| + base::Closure release_callback_;
|
| +
|
| + base::WeakPtrFactory<StreamTexture> weak_factory_;
|
| + DISALLOW_COPY_AND_ASSIGN(StreamTexture);
|
| +};
|
| +
|
| // static
|
| -bool StreamTexture::Create(
|
| +scoped_refptr<StreamTexture> StreamTexture::Create(
|
| GpuCommandBufferStub* owner_stub,
|
| uint32 client_texture_id,
|
| - int stream_id) {
|
| + int32 stream_id) {
|
| GLES2Decoder* decoder = owner_stub->decoder();
|
| TextureManager* texture_manager =
|
| decoder->GetContextGroup()->texture_manager();
|
| @@ -38,7 +140,7 @@ bool StreamTexture::Create(
|
|
|
| // TODO: Ideally a valid image id was returned to the client so that
|
| // it could then call glBindTexImage2D() for doing the following.
|
| - scoped_refptr<gl::GLImage> gl_image(
|
| + scoped_refptr<StreamTexture> gl_image(
|
| new StreamTexture(owner_stub, stream_id, texture->service_id()));
|
| gfx::Size size = gl_image->GetSize();
|
| texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES);
|
| @@ -48,10 +150,10 @@ bool StreamTexture::Create(
|
| texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0,
|
| gl_image.get(),
|
| gpu::gles2::Texture::UNBOUND);
|
| - return true;
|
| + return gl_image;
|
| }
|
|
|
| - return false;
|
| + return nullptr;
|
| }
|
|
|
| StreamTexture::StreamTexture(GpuCommandBufferStub* owner_stub,
|
| @@ -78,6 +180,7 @@ StreamTexture::~StreamTexture() {
|
| owner_stub_->RemoveDestructionObserver(this);
|
| owner_stub_->channel()->RemoveRoute(route_id_);
|
| }
|
| + release_callback_.Run();
|
| }
|
|
|
| void StreamTexture::OnWillDestroyStub() {
|
| @@ -195,7 +298,6 @@ bool StreamTexture::OnMessageReceived(const IPC::Message& message) {
|
| 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()
|
|
|
| @@ -248,4 +350,49 @@ void StreamTexture::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
|
| // TODO(ericrk): Add OnMemoryDump for GLImages. crbug.com/514914
|
| }
|
|
|
| +StreamTextureManager::StreamTextureManager() : weak_factory_(this) {}
|
| +
|
| +StreamTextureManager::~StreamTextureManager() {
|
| + if (!stream_textures_.empty()) {
|
| + LOG(WARNING) << "Undestroyed stream textures while tearing down "
|
| + "StreamTextureManager.";
|
| + }
|
| +}
|
| +
|
| +bool StreamTextureManager::CreateStreamTexture(GpuCommandBufferStub* owner_stub,
|
| + uint32 client_texture_id,
|
| + int32 stream_id) {
|
| + CalledOnValidThread();
|
| + DCHECK_EQ(static_cast<size_t>(0), stream_textures_.count(stream_id));
|
| + scoped_refptr<StreamTexture> stream_texture =
|
| + StreamTexture::Create(owner_stub, client_texture_id, stream_id);
|
| + if (!stream_texture)
|
| + return false;
|
| + base::Closure release_callback =
|
| + base::Bind(&StreamTextureManager::OnReleaseStreamTexture,
|
| + weak_factory_.GetWeakPtr(), stream_id);
|
| + stream_texture->SetReleaseCallback(release_callback);
|
| + stream_textures_[stream_id] = stream_texture.get();
|
| + return true;
|
| +}
|
| +
|
| +void StreamTextureManager::SetStreamTextureSize(
|
| + GpuCommandBufferStub* owner_stub,
|
| + uint32 client_texture_id,
|
| + int32 stream_id,
|
| + size_t width,
|
| + size_t height) {
|
| + CalledOnValidThread();
|
| + if (!stream_textures_.count(stream_id))
|
| + return;
|
| + stream_textures_[stream_id]->SetSize(owner_stub, client_texture_id, width,
|
| + height);
|
| +}
|
| +
|
| +void StreamTextureManager::OnReleaseStreamTexture(int32 stream_id) {
|
| + CalledOnValidThread();
|
| + DCHECK_EQ(static_cast<size_t>(1), stream_textures_.count(stream_id));
|
| + stream_textures_.erase(stream_id);
|
| +}
|
| +
|
| } // namespace content
|
|
|