cef/patch/patches/external_textures_1006.patch

1318 lines
56 KiB
Diff

diff --git content/browser/compositor/browser_compositor_output_surface.cc content/browser/compositor/browser_compositor_output_surface.cc
index 0a1231d4e16c..11e1cbc521d4 100644
--- content/browser/compositor/browser_compositor_output_surface.cc
+++ content/browser/compositor/browser_compositor_output_surface.cc
@@ -53,6 +53,10 @@ void BrowserCompositorOutputSurface::SetReflector(ReflectorImpl* reflector) {
OnReflectorChanged();
}
+void* BrowserCompositorOutputSurface::GetSharedTexture() const {
+ return nullptr;
+}
+
void BrowserCompositorOutputSurface::OnReflectorChanged() {
}
diff --git content/browser/compositor/browser_compositor_output_surface.h content/browser/compositor/browser_compositor_output_surface.h
index 3c4d448b972f..fa3f01f59484 100644
--- content/browser/compositor/browser_compositor_output_surface.h
+++ content/browser/compositor/browser_compositor_output_surface.h
@@ -40,6 +40,8 @@ class CONTENT_EXPORT BrowserCompositorOutputSurface
void SetReflector(ReflectorImpl* reflector);
+ virtual void* GetSharedTexture() const;
+
// Called when |reflector_| was updated.
virtual void OnReflectorChanged();
diff --git content/browser/compositor/gpu_process_transport_factory.cc content/browser/compositor/gpu_process_transport_factory.cc
index 0da5e9c1ecbc..49c79455b4aa 100644
--- content/browser/compositor/gpu_process_transport_factory.cc
+++ content/browser/compositor/gpu_process_transport_factory.cc
@@ -208,6 +208,18 @@ GpuProcessTransportFactory::~GpuProcessTransportFactory() {
task_graph_runner_->Shutdown();
}
+void* GpuProcessTransportFactory::GetSharedTexture(ui::Compositor* compositor) {
+ PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
+ if (it == per_compositor_data_.end())
+ return nullptr;
+ PerCompositorData* data = it->second.get();
+ DCHECK(data);
+
+ if (data->display_output_surface)
+ return data->display_output_surface->GetSharedTexture();
+ return nullptr;
+}
+
std::unique_ptr<viz::SoftwareOutputDevice>
GpuProcessTransportFactory::CreateSoftwareOutputDevice(
gfx::AcceleratedWidget widget,
@@ -450,11 +462,20 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
// surfaces as they are not following the correct mode.
DisableGpuCompositing(compositor.get());
}
+
+ std::unique_ptr<viz::SoftwareOutputDevice> output_device;
+ if (compositor->delegate()) {
+ output_device = compositor->delegate()->CreateSoftwareOutputDevice(
+ compositor.get());
+ }
+ if (!output_device) {
+ output_device = CreateSoftwareOutputDevice(compositor->widget(),
+ compositor->task_runner());
+ }
+
display_output_surface =
std::make_unique<SoftwareBrowserCompositorOutputSurface>(
- CreateSoftwareOutputDevice(compositor->widget(),
- compositor->task_runner()),
- std::move(vsync_callback));
+ std::move(output_device), std::move(vsync_callback));
} else {
DCHECK(context_provider);
const auto& capabilities = context_provider->ContextCapabilities();
@@ -462,7 +483,8 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
display_output_surface =
std::make_unique<OffscreenBrowserCompositorOutputSurface>(
context_provider, std::move(vsync_callback),
- std::unique_ptr<viz::CompositorOverlayCandidateValidator>());
+ std::unique_ptr<viz::CompositorOverlayCandidateValidator>(),
+ compositor->shared_texture_enabled());
} else if (capabilities.surfaceless) {
#if defined(OS_MACOSX)
const auto& gpu_feature_info = context_provider->GetGpuFeatureInfo();
@@ -914,7 +936,8 @@ GpuProcessTransportFactory::CreatePerCompositorData(
gfx::AcceleratedWidget widget = compositor->widget();
auto data = std::make_unique<PerCompositorData>();
- if (widget == gfx::kNullAcceleratedWidget) {
+ if (widget == gfx::kNullAcceleratedWidget ||
+ compositor->shared_texture_enabled()) {
data->surface_handle = gpu::kNullSurfaceHandle;
} else {
#if defined(GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW)
diff --git content/browser/compositor/gpu_process_transport_factory.h content/browser/compositor/gpu_process_transport_factory.h
index 525fa0c06b33..1f95b4f53496 100644
--- content/browser/compositor/gpu_process_transport_factory.h
+++ content/browser/compositor/gpu_process_transport_factory.h
@@ -101,6 +101,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void IssueExternalBeginFrame(ui::Compositor* compositor,
const viz::BeginFrameArgs& args) override;
void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override;
+ void* GetSharedTexture(ui::Compositor* compositor) override;
// ImageTransportFactory implementation.
void DisableGpuCompositing() override;
diff --git content/browser/compositor/offscreen_browser_compositor_output_surface.cc content/browser/compositor/offscreen_browser_compositor_output_surface.cc
index e719683c37e9..a51294913fc4 100644
--- content/browser/compositor/offscreen_browser_compositor_output_surface.cc
+++ content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -34,10 +34,12 @@ OffscreenBrowserCompositorOutputSurface::
scoped_refptr<ws::ContextProviderCommandBuffer> context,
const UpdateVSyncParametersCallback& update_vsync_parameters_callback,
std::unique_ptr<viz::CompositorOverlayCandidateValidator>
- overlay_candidate_validator)
+ overlay_candidate_validator,
+ bool shared_texture_enabled)
: BrowserCompositorOutputSurface(std::move(context),
update_vsync_parameters_callback,
std::move(overlay_candidate_validator)),
+ shared_texture_enabled_(shared_texture_enabled),
weak_ptr_factory_(this) {
capabilities_.uses_default_gl_framebuffer = false;
}
@@ -47,6 +49,10 @@ OffscreenBrowserCompositorOutputSurface::
DiscardBackbuffer();
}
+void* OffscreenBrowserCompositorOutputSurface::GetSharedTexture() const {
+ return (void*)shared_handle_;
+}
+
void OffscreenBrowserCompositorOutputSurface::BindToClient(
viz::OutputSurfaceClient* client) {
DCHECK(client);
@@ -55,42 +61,72 @@ void OffscreenBrowserCompositorOutputSurface::BindToClient(
}
void OffscreenBrowserCompositorOutputSurface::EnsureBackbuffer() {
- bool update_source_texture = !reflector_texture_ || reflector_changed_;
- reflector_changed_ = false;
- if (!reflector_texture_) {
- reflector_texture_.reset(new ReflectorTexture(context_provider()));
-
- GLES2Interface* gl = context_provider_->ContextGL();
-
- const int max_texture_size =
- context_provider_->ContextCapabilities().max_texture_size;
- int texture_width = std::min(max_texture_size, reshape_size_.width());
- int texture_height = std::min(max_texture_size, reshape_size_.height());
-
- gl->BindTexture(GL_TEXTURE_2D, reflector_texture_->texture_id());
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(kFboTextureFormat),
- texture_width, texture_height, 0,
- GLDataFormat(kFboTextureFormat),
- GLDataType(kFboTextureFormat), nullptr);
+ GLES2Interface* gl = context_provider_->ContextGL();
+
+ const int max_texture_size =
+ context_provider_->ContextCapabilities().max_texture_size;
+ int texture_width = std::min(max_texture_size, reshape_size_.width());
+ int texture_height = std::min(max_texture_size, reshape_size_.height());
+
+ GLuint color_attachment = 0;
+
+ if (shared_texture_enabled_) {
+ if (!shared_handle_ && (texture_width > 0) && (texture_height > 0)) {
+ gl->GenTextures(1, &shared_texture_);
+ gl->BindTexture(GL_TEXTURE_2D, shared_texture_);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ shared_handle_ = gl->CreateSharedTexture(shared_texture_, texture_width,
+ texture_height);
+
+ if (shared_handle_) {
+ color_attachment = shared_texture_;
+ } else {
+ gl->DeleteTextures(1, &shared_texture_);
+ shared_texture_ = 0;
+ }
+ }
+ } else {
+ // The shared texture code above in theory could work with the reflector
+ // texture However, there were issues making associating it a shared surface
+ // and then attaching it to the FBO (incomplete?)
+ bool update_source_texture = !reflector_texture_ || reflector_changed_;
+ reflector_changed_ = false;
+ if (!reflector_texture_) {
+ reflector_texture_.reset(new ReflectorTexture(context_provider()));
+
+ gl->BindTexture(GL_TEXTURE_2D, reflector_texture_->texture_id());
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(kFboTextureFormat),
+ texture_width, texture_height, 0,
+ GLDataFormat(kFboTextureFormat),
+ GLDataType(kFboTextureFormat), nullptr);
+
+ color_attachment = reflector_texture_->texture_id();
+
+ // The reflector may be created later or detached and re-attached,
+ // so don't assume it always exists. For example, ChromeOS always
+ // creates a reflector asynchronosly when creating this for software
+ // mirroring. See |DisplayManager::CreateMirrorWindowAsyncIfAny|.
+ if (reflector_ && update_source_texture)
+ reflector_->OnSourceTextureMailboxUpdated(
+ reflector_texture_->mailbox());
+ }
+ }
+
+ if (color_attachment) {
if (!fbo_)
gl->GenFramebuffers(1, &fbo_);
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, reflector_texture_->texture_id(),
- 0);
+ GL_TEXTURE_2D, color_attachment, 0);
}
-
- // The reflector may be created later or detached and re-attached,
- // so don't assume it always exists. For example, ChromeOS always
- // creates a reflector asynchronosly when creating this for software
- // mirroring. See |DisplayManager::CreateMirrorWindowAsyncIfAny|.
- if (reflector_ && update_source_texture)
- reflector_->OnSourceTextureMailboxUpdated(reflector_texture_->mailbox());
}
void OffscreenBrowserCompositorOutputSurface::DiscardBackbuffer() {
@@ -102,6 +138,16 @@ void OffscreenBrowserCompositorOutputSurface::DiscardBackbuffer() {
reflector_->OnSourceTextureMailboxUpdated(nullptr);
}
+ if (shared_handle_) {
+ gl->DeleteSharedTexture(shared_handle_);
+ shared_handle_ = 0ull;
+ }
+
+ if (shared_texture_) {
+ gl->DeleteTextures(1, &shared_texture_);
+ shared_texture_ = 0;
+ }
+
if (fbo_) {
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
gl->DeleteFramebuffers(1, &fbo_);
@@ -124,15 +170,20 @@ void OffscreenBrowserCompositorOutputSurface::Reshape(
}
void OffscreenBrowserCompositorOutputSurface::BindFramebuffer() {
- bool need_to_bind = !!reflector_texture_.get();
+ GLES2Interface* gl = context_provider_->ContextGL();
+ bool need_to_bind = !!reflector_texture_.get();
EnsureBackbuffer();
- DCHECK(reflector_texture_.get());
DCHECK(fbo_);
- if (need_to_bind) {
- GLES2Interface* gl = context_provider_->ContextGL();
+ if (shared_handle_) {
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ gl->LockSharedTexture(shared_handle_);
+ } else {
+ DCHECK(reflector_texture_.get());
+ if (need_to_bind) {
+ gl->BindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ }
}
}
@@ -153,6 +204,12 @@ void OffscreenBrowserCompositorOutputSurface::SwapBuffers(
// The original implementation had a flickering issue (crbug.com/515332).
gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
+ // If using a shared texture we need to Flush.
+ if (shared_handle_) {
+ gl->UnlockSharedTexture(shared_handle_);
+ gl->Flush();
+ }
+
gpu::SyncToken sync_token;
gl->GenUnverifiedSyncTokenCHROMIUM(sync_token.GetData());
context_provider_->ContextSupport()->SignalSyncToken(
@@ -192,7 +249,9 @@ void OffscreenBrowserCompositorOutputSurface::OnSwapBuffersComplete(
const std::vector<ui::LatencyInfo>& latency_info) {
latency_tracker_.OnGpuSwapBuffersCompleted(latency_info);
client_->DidReceiveSwapBuffersAck();
- client_->DidReceivePresentationFeedback(gfx::PresentationFeedback());
+ gfx::PresentationFeedback feedback;
+ feedback.timestamp = base::TimeTicks::Now();
+ client_->DidReceivePresentationFeedback(feedback);
}
unsigned OffscreenBrowserCompositorOutputSurface::UpdateGpuFence() {
diff --git content/browser/compositor/offscreen_browser_compositor_output_surface.h content/browser/compositor/offscreen_browser_compositor_output_surface.h
index 71830777ae56..6a0857b02a04 100644
--- content/browser/compositor/offscreen_browser_compositor_output_surface.h
+++ content/browser/compositor/offscreen_browser_compositor_output_surface.h
@@ -31,7 +31,8 @@ class OffscreenBrowserCompositorOutputSurface
scoped_refptr<ws::ContextProviderCommandBuffer> context,
const UpdateVSyncParametersCallback& update_vsync_parameters_callback,
std::unique_ptr<viz::CompositorOverlayCandidateValidator>
- overlay_candidate_validator);
+ overlay_candidate_validator,
+ bool shared_texture_enabled);
~OffscreenBrowserCompositorOutputSurface() override;
@@ -53,11 +54,15 @@ class OffscreenBrowserCompositorOutputSurface
gfx::BufferFormat GetOverlayBufferFormat() const override;
uint32_t GetFramebufferCopyTextureFormat() override;
+ void* GetSharedTexture() const override;
+
// BrowserCompositorOutputSurface implementation.
void OnReflectorChanged() override;
unsigned UpdateGpuFence() override;
+ void NotifyRenderHost(const std::vector<ui::LatencyInfo>& latency_info);
+
void OnSwapBuffersComplete(const std::vector<ui::LatencyInfo>& latency_info);
viz::OutputSurfaceClient* client_ = nullptr;
@@ -65,6 +70,11 @@ class OffscreenBrowserCompositorOutputSurface
uint32_t fbo_ = 0;
bool reflector_changed_ = false;
std::unique_ptr<ReflectorTexture> reflector_texture_;
+
+ bool shared_texture_enabled_ = false;
+ uint64_t shared_handle_ = 0ull;
+ uint32_t shared_texture_ = 0;
+
ui::LatencyTracker latency_tracker_;
base::WeakPtrFactory<OffscreenBrowserCompositorOutputSurface>
weak_ptr_factory_;
diff --git gpu/GLES2/gl2chromium_autogen.h gpu/GLES2/gl2chromium_autogen.h
index 404c05cee78b..d2ce3e8de6e9 100644
--- gpu/GLES2/gl2chromium_autogen.h
+++ gpu/GLES2/gl2chromium_autogen.h
@@ -416,6 +416,10 @@
GLES2_GET_FUN(CreateClientGpuFenceCHROMIUM)
#define glWaitGpuFenceCHROMIUM GLES2_GET_FUN(WaitGpuFenceCHROMIUM)
#define glDestroyGpuFenceCHROMIUM GLES2_GET_FUN(DestroyGpuFenceCHROMIUM)
+#define glCreateSharedTexture GLES2_GET_FUN(CreateSharedTexture)
+#define glLockSharedTexture GLES2_GET_FUN(LockSharedTexture)
+#define glUnlockSharedTexture GLES2_GET_FUN(UnlockSharedTexture)
+#define glDeleteSharedTexture GLES2_GET_FUN(DeleteSharedTexture)
#define glInvalidateReadbackBufferShadowDataCHROMIUM \
GLES2_GET_FUN(InvalidateReadbackBufferShadowDataCHROMIUM)
#define glFramebufferTextureMultiviewLayeredANGLE \
diff --git gpu/command_buffer/build_gles2_cmd_buffer.py gpu/command_buffer/build_gles2_cmd_buffer.py
index 4032b2491109..02639f9b2080 100755
--- gpu/command_buffer/build_gles2_cmd_buffer.py
+++ gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4254,6 +4254,35 @@ _FUNCTION_INFO = {
'extension': 'CHROMIUM_gpu_fence',
'extension_flag': 'chromium_gpu_fence',
},
+ 'CreateSharedTexture': {
+ 'type': 'Custom',
+ 'data_transfer_methods': ['shm'],
+ 'cmd_args': 'GLint texture_id, GLint width, '
+ 'GLint height, GLuint64* result',
+ 'result': ['GLuint64'],
+ 'unit_test': False,
+ 'impl_func': False,
+ 'client_test': False,
+ 'extension': True,
+ },
+ 'LockSharedTexture': {
+ 'type': 'Custom',
+ 'unit_test': False,
+ 'client_test': False,
+ 'extension': True,
+ },
+ 'UnlockSharedTexture': {
+ 'type': 'Custom',
+ 'unit_test': False,
+ 'client_test': False,
+ 'extension': True,
+ },
+ 'DeleteSharedTexture': {
+ 'type': 'Custom',
+ 'unit_test': False,
+ 'client_test': False,
+ 'extension': True,
+ },
'UnpremultiplyAndDitherCopyCHROMIUM': {
'decoder_func': 'DoUnpremultiplyAndDitherCopyCHROMIUM',
'cmd_args': 'GLuint source_id, GLuint dest_id, GLint x, GLint y, '
diff --git gpu/command_buffer/client/gles2_c_lib_autogen.h gpu/command_buffer/client/gles2_c_lib_autogen.h
index b68942087179..2248762fcd77 100644
--- gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1909,6 +1909,20 @@ void GL_APIENTRY GLES2WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) {
void GL_APIENTRY GLES2DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) {
gles2::GetGLContext()->DestroyGpuFenceCHROMIUM(gpu_fence_id);
}
+GLuint64 GL_APIENTRY GLES2CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) {
+ return gles2::GetGLContext()->CreateSharedTexture(texture_id, width, height);
+}
+void GL_APIENTRY GLES2LockSharedTexture(GLuint64 shared_handle) {
+ gles2::GetGLContext()->LockSharedTexture(shared_handle);
+}
+void GL_APIENTRY GLES2UnlockSharedTexture(GLuint64 shared_handle) {
+ gles2::GetGLContext()->UnlockSharedTexture(shared_handle);
+}
+void GL_APIENTRY GLES2DeleteSharedTexture(GLuint64 shared_handle) {
+ gles2::GetGLContext()->DeleteSharedTexture(shared_handle);
+}
void GL_APIENTRY
GLES2InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) {
gles2::GetGLContext()->InvalidateReadbackBufferShadowDataCHROMIUM(buffer_id);
@@ -3434,6 +3448,22 @@ extern const NameToFunc g_gles2_function_table[] = {
"glDestroyGpuFenceCHROMIUM",
reinterpret_cast<GLES2FunctionPointer>(glDestroyGpuFenceCHROMIUM),
},
+ {
+ "glCreateSharedTexture",
+ reinterpret_cast<GLES2FunctionPointer>(glCreateSharedTexture),
+ },
+ {
+ "glLockSharedTexture",
+ reinterpret_cast<GLES2FunctionPointer>(glLockSharedTexture),
+ },
+ {
+ "glUnlockSharedTexture",
+ reinterpret_cast<GLES2FunctionPointer>(glUnlockSharedTexture),
+ },
+ {
+ "glDeleteSharedTexture",
+ reinterpret_cast<GLES2FunctionPointer>(glDeleteSharedTexture),
+ },
{
"glInvalidateReadbackBufferShadowDataCHROMIUM",
reinterpret_cast<GLES2FunctionPointer>(
diff --git gpu/command_buffer/client/gles2_cmd_helper_autogen.h gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index e2ac01959e22..83fb39054432 100644
--- gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3521,6 +3521,42 @@ void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) {
}
}
+void CreateSharedTexture(GLint texture_id,
+ GLint width,
+ GLint height,
+ uint32_t result_shm_id,
+ uint32_t result_shm_offset) {
+ gles2::cmds::CreateSharedTexture* c =
+ GetCmdSpace<gles2::cmds::CreateSharedTexture>();
+ if (c) {
+ c->Init(texture_id, width, height, result_shm_id, result_shm_offset);
+ }
+}
+
+void LockSharedTexture(GLuint64 shared_handle) {
+ gles2::cmds::LockSharedTexture* c =
+ GetCmdSpace<gles2::cmds::LockSharedTexture>();
+ if (c) {
+ c->Init(shared_handle);
+ }
+}
+
+void UnlockSharedTexture(GLuint64 shared_handle) {
+ gles2::cmds::UnlockSharedTexture* c =
+ GetCmdSpace<gles2::cmds::UnlockSharedTexture>();
+ if (c) {
+ c->Init(shared_handle);
+ }
+}
+
+void DeleteSharedTexture(GLuint64 shared_handle) {
+ gles2::cmds::DeleteSharedTexture* c =
+ GetCmdSpace<gles2::cmds::DeleteSharedTexture>();
+ if (c) {
+ c->Init(shared_handle);
+ }
+}
+
void SetReadbackBufferShadowAllocationINTERNAL(GLuint buffer_id,
GLint shm_id,
GLuint shm_offset,
diff --git gpu/command_buffer/client/gles2_implementation.cc gpu/command_buffer/client/gles2_implementation.cc
index e748a48a8e2a..a92b41df54d3 100644
--- gpu/command_buffer/client/gles2_implementation.cc
+++ gpu/command_buffer/client/gles2_implementation.cc
@@ -7687,6 +7687,22 @@ void GLES2Implementation::Viewport(GLint x,
CheckGLError();
}
+GLuint64 GLES2Implementation::CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) {
+ typedef cmds::CreateSharedTexture::Result Result;
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return 0;
+ }
+ *result = 0;
+ helper_->CreateSharedTexture(texture_id, width, height, GetResultShmId(),
+ result.offset());
+
+ WaitForCmd();
+ return *result;
+}
+
void GLES2Implementation::IssueBeginQuery(GLenum target,
GLuint id,
uint32_t sync_data_shm_id,
diff --git gpu/command_buffer/client/gles2_implementation_autogen.h gpu/command_buffer/client/gles2_implementation_autogen.h
index 6882d12a79c4..b237ee953860 100644
--- gpu/command_buffer/client/gles2_implementation_autogen.h
+++ gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1345,6 +1345,16 @@ void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
+GLuint64 CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) override;
+
+void LockSharedTexture(GLuint64 shared_handle) override;
+
+void UnlockSharedTexture(GLuint64 shared_handle) override;
+
+void DeleteSharedTexture(GLuint64 shared_handle) override;
+
void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
diff --git gpu/command_buffer/client/gles2_implementation_impl_autogen.h gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 13b36769ae3d..d2351bb96021 100644
--- gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3790,6 +3790,30 @@ void GLES2Implementation::DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) {
CheckGLError();
}
+void GLES2Implementation::LockSharedTexture(GLuint64 shared_handle) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLockSharedTexture("
+ << shared_handle << ")");
+ helper_->LockSharedTexture(shared_handle);
+ CheckGLError();
+}
+
+void GLES2Implementation::UnlockSharedTexture(GLuint64 shared_handle) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnlockSharedTexture("
+ << shared_handle << ")");
+ helper_->UnlockSharedTexture(shared_handle);
+ CheckGLError();
+}
+
+void GLES2Implementation::DeleteSharedTexture(GLuint64 shared_handle) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteSharedTexture("
+ << shared_handle << ")");
+ helper_->DeleteSharedTexture(shared_handle);
+ CheckGLError();
+}
+
void GLES2Implementation::FramebufferTextureMultiviewLayeredANGLE(
GLenum target,
GLenum attachment,
diff --git gpu/command_buffer/client/gles2_interface_autogen.h gpu/command_buffer/client/gles2_interface_autogen.h
index 2071473f0da8..77a29e65cafd 100644
--- gpu/command_buffer/client/gles2_interface_autogen.h
+++ gpu/command_buffer/client/gles2_interface_autogen.h
@@ -1010,6 +1010,12 @@ virtual GLuint CreateGpuFenceCHROMIUM() = 0;
virtual GLuint CreateClientGpuFenceCHROMIUM(ClientGpuFence source) = 0;
virtual void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0;
virtual void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0;
+virtual GLuint64 CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) = 0;
+virtual void LockSharedTexture(GLuint64 shared_handle) = 0;
+virtual void UnlockSharedTexture(GLuint64 shared_handle) = 0;
+virtual void DeleteSharedTexture(GLuint64 shared_handle) = 0;
virtual void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) = 0;
virtual void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
GLenum attachment,
diff --git gpu/command_buffer/client/gles2_interface_stub_autogen.h gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 158134cf608e..2990494dcc5e 100644
--- gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -980,6 +980,12 @@ GLuint CreateGpuFenceCHROMIUM() override;
GLuint CreateClientGpuFenceCHROMIUM(ClientGpuFence source) override;
void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
+GLuint64 CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) override;
+void LockSharedTexture(GLuint64 shared_handle) override;
+void UnlockSharedTexture(GLuint64 shared_handle) override;
+void DeleteSharedTexture(GLuint64 shared_handle) override;
void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
GLenum attachment,
diff --git gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index 29d079725c72..444c60df71a4 100644
--- gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1303,6 +1303,14 @@ GLuint GLES2InterfaceStub::CreateClientGpuFenceCHROMIUM(
}
void GLES2InterfaceStub::WaitGpuFenceCHROMIUM(GLuint /* gpu_fence_id */) {}
void GLES2InterfaceStub::DestroyGpuFenceCHROMIUM(GLuint /* gpu_fence_id */) {}
+GLuint64 GLES2InterfaceStub::CreateSharedTexture(GLuint /* texture_id */,
+ GLsizei /* width */,
+ GLsizei /* height */) {
+ return 0;
+}
+void GLES2InterfaceStub::LockSharedTexture(GLuint64 /* shared_handle */) {}
+void GLES2InterfaceStub::UnlockSharedTexture(GLuint64 /* shared_handle */) {}
+void GLES2InterfaceStub::DeleteSharedTexture(GLuint64 /* shared_handle */) {}
void GLES2InterfaceStub::InvalidateReadbackBufferShadowDataCHROMIUM(
GLuint /* buffer_id */) {}
void GLES2InterfaceStub::FramebufferTextureMultiviewLayeredANGLE(
diff --git gpu/command_buffer/client/gles2_trace_implementation_autogen.h gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index 7e94db26455d..d9de7879ea9a 100644
--- gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -980,6 +980,12 @@ GLuint CreateGpuFenceCHROMIUM() override;
GLuint CreateClientGpuFenceCHROMIUM(ClientGpuFence source) override;
void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override;
+GLuint64 CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) override;
+void LockSharedTexture(GLuint64 shared_handle) override;
+void UnlockSharedTexture(GLuint64 shared_handle) override;
+void DeleteSharedTexture(GLuint64 shared_handle) override;
void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override;
void FramebufferTextureMultiviewLayeredANGLE(GLenum target,
GLenum attachment,
diff --git gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index 4b7932e147b0..b0f5f2cafae3 100644
--- gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2747,6 +2747,28 @@ void GLES2TraceImplementation::DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) {
gl_->DestroyGpuFenceCHROMIUM(gpu_fence_id);
}
+GLuint64 GLES2TraceImplementation::CreateSharedTexture(GLuint texture_id,
+ GLsizei width,
+ GLsizei height) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateSharedTexture");
+ return gl_->CreateSharedTexture(texture_id, width, height);
+}
+
+void GLES2TraceImplementation::LockSharedTexture(GLuint64 shared_handle) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::LockSharedTexture");
+ gl_->LockSharedTexture(shared_handle);
+}
+
+void GLES2TraceImplementation::UnlockSharedTexture(GLuint64 shared_handle) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UnlockSharedTexture");
+ gl_->UnlockSharedTexture(shared_handle);
+}
+
+void GLES2TraceImplementation::DeleteSharedTexture(GLuint64 shared_handle) {
+ TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DeleteSharedTexture");
+ gl_->DeleteSharedTexture(shared_handle);
+}
+
void GLES2TraceImplementation::InvalidateReadbackBufferShadowDataCHROMIUM(
GLuint buffer_id) {
TRACE_EVENT_BINARY_EFFICIENT0(
diff --git gpu/command_buffer/common/gles2_cmd_format_autogen.h gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 2a59e11c2d25..fbb6c4551d70 100644
--- gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -17336,6 +17336,193 @@ static_assert(offsetof(DestroyGpuFenceCHROMIUM, header) == 0,
static_assert(offsetof(DestroyGpuFenceCHROMIUM, gpu_fence_id) == 4,
"offset of DestroyGpuFenceCHROMIUM gpu_fence_id should be 4");
+struct CreateSharedTexture {
+ typedef CreateSharedTexture ValueType;
+ static const CommandId kCmdId = kCreateSharedTexture;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ typedef GLuint64 Result;
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLint _texture_id,
+ GLint _width,
+ GLint _height,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ SetHeader();
+ texture_id = _texture_id;
+ width = _width;
+ height = _height;
+ result_shm_id = _result_shm_id;
+ result_shm_offset = _result_shm_offset;
+ }
+
+ void* Set(void* cmd,
+ GLint _texture_id,
+ GLint _width,
+ GLint _height,
+ uint32_t _result_shm_id,
+ uint32_t _result_shm_offset) {
+ static_cast<ValueType*>(cmd)->Init(_texture_id, _width, _height,
+ _result_shm_id, _result_shm_offset);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ int32_t texture_id;
+ int32_t width;
+ int32_t height;
+ uint32_t result_shm_id;
+ uint32_t result_shm_offset;
+};
+
+static_assert(sizeof(CreateSharedTexture) == 24,
+ "size of CreateSharedTexture should be 24");
+static_assert(offsetof(CreateSharedTexture, header) == 0,
+ "offset of CreateSharedTexture header should be 0");
+static_assert(offsetof(CreateSharedTexture, texture_id) == 4,
+ "offset of CreateSharedTexture texture_id should be 4");
+static_assert(offsetof(CreateSharedTexture, width) == 8,
+ "offset of CreateSharedTexture width should be 8");
+static_assert(offsetof(CreateSharedTexture, height) == 12,
+ "offset of CreateSharedTexture height should be 12");
+static_assert(offsetof(CreateSharedTexture, result_shm_id) == 16,
+ "offset of CreateSharedTexture result_shm_id should be 16");
+static_assert(offsetof(CreateSharedTexture, result_shm_offset) == 20,
+ "offset of CreateSharedTexture result_shm_offset should be 20");
+
+struct LockSharedTexture {
+ typedef LockSharedTexture ValueType;
+ static const CommandId kCmdId = kLockSharedTexture;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint64 _shared_handle) {
+ SetHeader();
+ GLES2Util::MapUint64ToTwoUint32(static_cast<uint64_t>(_shared_handle),
+ &shared_handle_0, &shared_handle_1);
+ }
+
+ void* Set(void* cmd, GLuint64 _shared_handle) {
+ static_cast<ValueType*>(cmd)->Init(_shared_handle);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ GLuint64 shared_handle() const volatile {
+ return static_cast<GLuint64>(
+ GLES2Util::MapTwoUint32ToUint64(shared_handle_0, shared_handle_1));
+ }
+
+ gpu::CommandHeader header;
+ uint32_t shared_handle_0;
+ uint32_t shared_handle_1;
+};
+
+static_assert(sizeof(LockSharedTexture) == 12,
+ "size of LockSharedTexture should be 12");
+static_assert(offsetof(LockSharedTexture, header) == 0,
+ "offset of LockSharedTexture header should be 0");
+static_assert(offsetof(LockSharedTexture, shared_handle_0) == 4,
+ "offset of LockSharedTexture shared_handle_0 should be 4");
+static_assert(offsetof(LockSharedTexture, shared_handle_1) == 8,
+ "offset of LockSharedTexture shared_handle_1 should be 8");
+
+struct UnlockSharedTexture {
+ typedef UnlockSharedTexture ValueType;
+ static const CommandId kCmdId = kUnlockSharedTexture;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint64 _shared_handle) {
+ SetHeader();
+ GLES2Util::MapUint64ToTwoUint32(static_cast<uint64_t>(_shared_handle),
+ &shared_handle_0, &shared_handle_1);
+ }
+
+ void* Set(void* cmd, GLuint64 _shared_handle) {
+ static_cast<ValueType*>(cmd)->Init(_shared_handle);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ GLuint64 shared_handle() const volatile {
+ return static_cast<GLuint64>(
+ GLES2Util::MapTwoUint32ToUint64(shared_handle_0, shared_handle_1));
+ }
+
+ gpu::CommandHeader header;
+ uint32_t shared_handle_0;
+ uint32_t shared_handle_1;
+};
+
+static_assert(sizeof(UnlockSharedTexture) == 12,
+ "size of UnlockSharedTexture should be 12");
+static_assert(offsetof(UnlockSharedTexture, header) == 0,
+ "offset of UnlockSharedTexture header should be 0");
+static_assert(offsetof(UnlockSharedTexture, shared_handle_0) == 4,
+ "offset of UnlockSharedTexture shared_handle_0 should be 4");
+static_assert(offsetof(UnlockSharedTexture, shared_handle_1) == 8,
+ "offset of UnlockSharedTexture shared_handle_1 should be 8");
+
+struct DeleteSharedTexture {
+ typedef DeleteSharedTexture ValueType;
+ static const CommandId kCmdId = kDeleteSharedTexture;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+ static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+ static uint32_t ComputeSize() {
+ return static_cast<uint32_t>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() { header.SetCmd<ValueType>(); }
+
+ void Init(GLuint64 _shared_handle) {
+ SetHeader();
+ GLES2Util::MapUint64ToTwoUint32(static_cast<uint64_t>(_shared_handle),
+ &shared_handle_0, &shared_handle_1);
+ }
+
+ void* Set(void* cmd, GLuint64 _shared_handle) {
+ static_cast<ValueType*>(cmd)->Init(_shared_handle);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ GLuint64 shared_handle() const volatile {
+ return static_cast<GLuint64>(
+ GLES2Util::MapTwoUint32ToUint64(shared_handle_0, shared_handle_1));
+ }
+
+ gpu::CommandHeader header;
+ uint32_t shared_handle_0;
+ uint32_t shared_handle_1;
+};
+
+static_assert(sizeof(DeleteSharedTexture) == 12,
+ "size of DeleteSharedTexture should be 12");
+static_assert(offsetof(DeleteSharedTexture, header) == 0,
+ "offset of DeleteSharedTexture header should be 0");
+static_assert(offsetof(DeleteSharedTexture, shared_handle_0) == 4,
+ "offset of DeleteSharedTexture shared_handle_0 should be 4");
+static_assert(offsetof(DeleteSharedTexture, shared_handle_1) == 8,
+ "offset of DeleteSharedTexture shared_handle_1 should be 8");
+
struct SetReadbackBufferShadowAllocationINTERNAL {
typedef SetReadbackBufferShadowAllocationINTERNAL ValueType;
static const CommandId kCmdId = kSetReadbackBufferShadowAllocationINTERNAL;
diff --git gpu/command_buffer/common/gles2_cmd_format_test_autogen.h gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 128473360af0..b4947682c816 100644
--- gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5721,6 +5721,52 @@ TEST_F(GLES2FormatTest, DestroyGpuFenceCHROMIUM) {
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, CreateSharedTexture) {
+ cmds::CreateSharedTexture& cmd = *GetBufferAs<cmds::CreateSharedTexture>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12),
+ static_cast<GLint>(13), static_cast<uint32_t>(14),
+ static_cast<uint32_t>(15));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::CreateSharedTexture::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLint>(11), cmd.texture_id);
+ EXPECT_EQ(static_cast<GLint>(12), cmd.width);
+ EXPECT_EQ(static_cast<GLint>(13), cmd.height);
+ EXPECT_EQ(static_cast<uint32_t>(14), cmd.result_shm_id);
+ EXPECT_EQ(static_cast<uint32_t>(15), cmd.result_shm_offset);
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, LockSharedTexture) {
+ cmds::LockSharedTexture& cmd = *GetBufferAs<cmds::LockSharedTexture>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint64>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::LockSharedTexture::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint64>(11), cmd.shared_handle());
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, UnlockSharedTexture) {
+ cmds::UnlockSharedTexture& cmd = *GetBufferAs<cmds::UnlockSharedTexture>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint64>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::UnlockSharedTexture::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint64>(11), cmd.shared_handle());
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, DeleteSharedTexture) {
+ cmds::DeleteSharedTexture& cmd = *GetBufferAs<cmds::DeleteSharedTexture>();
+ void* next_cmd = cmd.Set(&cmd, static_cast<GLuint64>(11));
+ EXPECT_EQ(static_cast<uint32_t>(cmds::DeleteSharedTexture::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLuint64>(11), cmd.shared_handle());
+ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, SetReadbackBufferShadowAllocationINTERNAL) {
cmds::SetReadbackBufferShadowAllocationINTERNAL& cmd =
*GetBufferAs<cmds::SetReadbackBufferShadowAllocationINTERNAL>();
diff --git gpu/command_buffer/common/gles2_cmd_ids_autogen.h gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index b3dd9b38feba..bcb3656e4481 100644
--- gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -361,7 +361,11 @@
OP(MaxShaderCompilerThreadsKHR) /* 602 */ \
OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 603 */ \
OP(BeginSharedImageAccessDirectCHROMIUM) /* 604 */ \
- OP(EndSharedImageAccessDirectCHROMIUM) /* 605 */
+ OP(EndSharedImageAccessDirectCHROMIUM) /* 605 */ \
+ OP(CreateSharedTexture) /* 606 */ \
+ OP(LockSharedTexture) /* 607 */ \
+ OP(UnlockSharedTexture) /* 608 */ \
+ OP(DeleteSharedTexture) /* 609 */
enum CommandId {
kOneBeforeStartPoint =
diff --git gpu/command_buffer/gles2_cmd_buffer_functions.txt gpu/command_buffer/gles2_cmd_buffer_functions.txt
index 2f9b93fda757..9897a2790587 100644
--- gpu/command_buffer/gles2_cmd_buffer_functions.txt
+++ gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -417,6 +417,12 @@ GL_APICALL GLuint GL_APIENTRY glCreateClientGpuFenceCHROMIUM (ClientGpuFen
GL_APICALL void GL_APIENTRY glWaitGpuFenceCHROMIUM (GLuint gpu_fence_id);
GL_APICALL void GL_APIENTRY glDestroyGpuFenceCHROMIUM (GLuint gpu_fence_id);
+// shared handle extensions
+GL_APICALL GLuint64 GL_APIENTRY glCreateSharedTexture (GLuint texture_id, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glLockSharedTexture (GLuint64 shared_handle);
+GL_APICALL void GL_APIENTRY glUnlockSharedTexture (GLuint64 shared_handle);
+GL_APICALL void GL_APIENTRY glDeleteSharedTexture (GLuint64 shared_handle);
+
// Extension CHROMIUM_nonblocking_readback
GL_APICALL void GL_APIENTRY glInvalidateReadbackBufferShadowDataCHROMIUM (GLidBuffer buffer_id);
// (used for CHROMIUM_nonblocking_readback implementation)
diff --git gpu/command_buffer/service/BUILD.gn gpu/command_buffer/service/BUILD.gn
index bbf81312c8d9..817a6b6fa421 100644
--- gpu/command_buffer/service/BUILD.gn
+++ gpu/command_buffer/service/BUILD.gn
@@ -107,6 +107,8 @@ target(link_target_type, "gles2_sources") {
visibility = [ "//gpu/*" ]
sources = [
+ "//cef/libcef/browser/gpu/external_texture_manager.cc",
+ "//cef/libcef/browser/gpu/external_texture_manager.h",
"abstract_texture.h",
"abstract_texture_impl_shared_context_state.cc",
"abstract_texture_impl_shared_context_state.h",
diff --git gpu/command_buffer/service/gles2_cmd_decoder.cc gpu/command_buffer/service/gles2_cmd_decoder.cc
index 5bb86a2a5d32..5439662701af 100644
--- gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -38,6 +38,7 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
+#include "cef/libcef/browser/gpu/external_texture_manager.h"
#include "gpu/command_buffer/common/debug_marker_manager.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
@@ -916,6 +917,13 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
return group_->mailbox_manager();
}
+ ExternalTextureManager* external_texture_manager() {
+ if (!external_texture_manager_.get()) {
+ external_texture_manager_.reset(new gles2::ExternalTextureManager());
+ }
+ return external_texture_manager_.get();
+ }
+
ImageManager* image_manager() { return group_->image_manager(); }
VertexArrayManager* vertex_array_manager() {
@@ -2644,6 +2652,8 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
std::unique_ptr<VertexArrayManager> vertex_array_manager_;
+ std::unique_ptr<ExternalTextureManager> external_texture_manager_;
+
base::flat_set<scoped_refptr<Buffer>> writes_submitted_but_not_completed_;
// The format of the back buffer_
@@ -5619,6 +5629,59 @@ error::Error GLES2DecoderImpl::HandleDestroyGpuFenceCHROMIUM(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleCreateSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::CreateSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::CreateSharedTexture*>(cmd_data);
+ GLuint texture_id = c.texture_id;
+ uint32_t width = c.width;
+ uint32_t height = c.height;
+
+ typedef cmds::CreateSharedTexture::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+
+ void* shared_handle = external_texture_manager()->CreateTexture(
+ texture_id, width, height, texture_manager());
+
+ *result_dst = (GLuint64)(shared_handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleLockSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::LockSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::LockSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->LockTexture(handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleUnlockSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::UnlockSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::UnlockSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->UnlockTexture(handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleDeleteSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::DeleteSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::DeleteSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->DeleteTexture(handle, texture_manager());
+ return error::kNoError;
+}
+
void GLES2DecoderImpl::CreateBackTexture() {
for (auto it = saved_back_textures_.begin(); it != saved_back_textures_.end();
++it) {
diff --git gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 2766bcbc5418..417f26076423 100644
--- gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
+#include "cef/libcef/browser/gpu/external_texture_manager.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/decoder_client.h"
#include "gpu/command_buffer/service/feature_info.h"
@@ -2512,6 +2513,67 @@ error::Error GLES2DecoderPassthroughImpl::CheckSwapBuffersResult(
return error::kNoError;
}
+ExternalTextureManager*
+GLES2DecoderPassthroughImpl::external_texture_manager() {
+ if (!external_texture_manager_.get()) {
+ external_texture_manager_.reset(new gles2::ExternalTextureManager());
+ }
+ return external_texture_manager_.get();
+}
+
+error::Error GLES2DecoderPassthroughImpl::HandleCreateSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::CreateSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::CreateSharedTexture*>(cmd_data);
+ GLuint texture_id = c.texture_id;
+ uint32_t width = c.width;
+ uint32_t height = c.height;
+
+ typedef cmds::CreateSharedTexture::Result Result;
+ Result* result_dst = GetSharedMemoryAs<Result*>(
+ c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
+ if (!result_dst) {
+ return error::kOutOfBounds;
+ }
+
+ void* shared_handle = external_texture_manager()->CreateTexture(
+ texture_id, width, height, nullptr);
+
+ *result_dst = (GLuint64)(shared_handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderPassthroughImpl::HandleLockSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::LockSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::LockSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->LockTexture(handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderPassthroughImpl::HandleUnlockSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::UnlockSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::UnlockSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->UnlockTexture(handle);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderPassthroughImpl::HandleDeleteSharedTexture(
+ uint32_t immediate_data_size,
+ const volatile void* cmd_data) {
+ const volatile gles2::cmds::DeleteSharedTexture& c =
+ *static_cast<const volatile gles2::cmds::DeleteSharedTexture*>(cmd_data);
+ void* handle = (void*)(c.shared_handle());
+ external_texture_manager()->DeleteTexture(handle, nullptr);
+ return error::kNoError;
+}
+
// static
GLES2DecoderPassthroughImpl::TextureTarget
GLES2DecoderPassthroughImpl::GLenumToTextureTarget(GLenum target) {
diff --git gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index ed682013976b..4bc28fe68a5d 100644
--- gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -45,6 +45,7 @@ class SharedImageRepresentationGLTexturePassthrough;
namespace gles2 {
class ContextGroup;
+class ExternalTextureManager;
class GPUTracer;
class MultiDrawManager;
class PassthroughAbstractTextureImpl;
@@ -377,6 +378,8 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
void SetOptionalExtensionsRequestedForTesting(bool request_extensions);
+ ExternalTextureManager* external_texture_manager();
+
void* GetScratchMemory(size_t size);
template <typename T>
@@ -580,6 +583,8 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
std::unique_ptr<MultiDrawManager> multi_draw_manager_;
+ std::unique_ptr<ExternalTextureManager> external_texture_manager_;
+
// State tracking of currently bound 2D textures (client IDs)
size_t active_texture_unit_;
diff --git ui/compositor/compositor.cc ui/compositor/compositor.cc
index 311c26b6e0ea..8583fdfecc19 100644
--- ui/compositor/compositor.cc
+++ ui/compositor/compositor.cc
@@ -555,6 +555,16 @@ scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const {
return vsync_manager_;
}
+void* Compositor::GetSharedTexture() {
+ if (context_factory_private_)
+ return context_factory_private_->GetSharedTexture(this);
+ return nullptr;
+}
+
+void Compositor::EnableSharedTexture(bool enable) {
+ shared_texture_enabled_ = enable;
+}
+
void Compositor::AddObserver(CompositorObserver* observer) {
observer_list_.AddObserver(observer);
}
diff --git ui/compositor/compositor.h ui/compositor/compositor.h
index 4e28277f7750..cd283ca49bd7 100644
--- ui/compositor/compositor.h
+++ ui/compositor/compositor.h
@@ -25,6 +25,7 @@
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id_allocation.h"
#include "components/viz/host/host_frame_sink_client.h"
+#include "components/viz/service/display/software_output_device.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/compositor/compositor_animation_observer.h"
@@ -160,6 +161,8 @@ class COMPOSITOR_EXPORT ContextFactoryPrivate {
const viz::BeginFrameArgs& args) = 0;
virtual void SetOutputIsSecure(Compositor* compositor, bool secure) = 0;
+
+ virtual void* GetSharedTexture(ui::Compositor* compositor) = 0;
};
// This class abstracts the creation of the 3D context for the compositor. It is
@@ -200,6 +203,17 @@ class COMPOSITOR_EXPORT ContextFactory {
virtual bool SyncTokensRequiredForDisplayCompositor() = 0;
};
+class COMPOSITOR_EXPORT CompositorDelegate {
+ public:
+ virtual std::unique_ptr<viz::SoftwareOutputDevice> CreateSoftwareOutputDevice(
+ ui::Compositor* compositor) {
+ return nullptr;
+ }
+
+ protected:
+ virtual ~CompositorDelegate() {}
+};
+
// Compositor object to take care of GPU painting.
// A Browser compositor object is responsible for generating the final
// displayable form of pixels comprising a single widget's contents. It draws an
@@ -242,6 +256,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
// Schedules a redraw of the layer tree associated with this compositor.
void ScheduleDraw();
+ CompositorDelegate* delegate() const { return delegate_; }
+ void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
+
// Sets the root of the layer tree drawn by this Compositor. The root layer
// must have no parent. The compositor's root layer is reset if the root layer
// is destroyed. NULL can be passed to reset the root layer, in which case the
@@ -355,6 +372,10 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
return task_runner_;
}
+ void* GetSharedTexture();
+ void EnableSharedTexture(bool enable);
+ bool shared_texture_enabled() const { return shared_texture_enabled_; }
+
// Compositor does not own observers. It is the responsibility of the
// observer to remove itself when it is done observing.
void AddObserver(CompositorObserver* observer);
@@ -465,6 +486,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
ui::ContextFactory* context_factory_;
ui::ContextFactoryPrivate* context_factory_private_;
+ CompositorDelegate* delegate_ = nullptr;
+
// The root of the Layer tree drawn by this compositor.
Layer* root_layer_ = nullptr;
@@ -499,6 +522,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
ExternalBeginFrameClient* const external_begin_frame_client_;
+ bool shared_texture_enabled_ = false;
+
const bool force_software_compositor_;
// The device scale factor of the monitor that this compositor is compositing
diff --git ui/compositor/host/host_context_factory_private.cc ui/compositor/host/host_context_factory_private.cc
index 2b23ed42a933..109841847888 100644
--- ui/compositor/host/host_context_factory_private.cc
+++ ui/compositor/host/host_context_factory_private.cc
@@ -254,6 +254,10 @@ void HostContextFactoryPrivate::SetOutputIsSecure(Compositor* compositor,
iter->second.display_private->SetOutputIsSecure(secure);
}
+void* HostContextFactoryPrivate::GetSharedTexture(Compositor* /*compositor*/) {
+ return nullptr;
+}
+
viz::FrameSinkManagerImpl* HostContextFactoryPrivate::GetFrameSinkManager() {
// When running with viz there is no FrameSinkManagerImpl in the browser
// process. FrameSinkManagerImpl runs in the GPU process instead. Anything in
diff --git ui/compositor/host/host_context_factory_private.h ui/compositor/host/host_context_factory_private.h
index 18cd096449d2..aa25ea058925 100644
--- ui/compositor/host/host_context_factory_private.h
+++ ui/compositor/host/host_context_factory_private.h
@@ -50,6 +50,8 @@ class HostContextFactoryPrivate : public ContextFactoryPrivate {
void UnconfigureCompositor(Compositor* compositor);
+ void* GetSharedTexture(ui::Compositor* compositor) override;
+
void set_is_gpu_compositing_disabled(bool value) {
is_gpu_compositing_disabled_ = value;
}