summaryrefslogtreecommitdiff
path: root/chromium/gpu/command_buffer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-18 16:35:47 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-11-18 15:45:54 +0000
commit32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch)
treeeeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/gpu/command_buffer
parent99677208ff3b216fdfec551fbe548da5520cd6fb (diff)
downloadqtwebengine-chromium-32f5a1c56531e4210bc4cf8d8c7825d66e081888.tar.gz
BASELINE: Update Chromium to 87.0.4280.67
Change-Id: Ib157360be8c2ffb2c73125751a89f60e049c1d54 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/gpu/command_buffer')
-rw-r--r--chromium/gpu/command_buffer/client/gl_helper_scaling.cc63
-rw-r--r--chromium/gpu/command_buffer/client/gles2_implementation.cc369
-rw-r--r--chromium/gpu/command_buffer/client/program_info_manager.cc43
-rw-r--r--chromium/gpu/command_buffer/client/program_info_manager.h28
-rw-r--r--chromium/gpu/command_buffer/client/shared_image_interface.h13
-rw-r--r--chromium/gpu/command_buffer/client/transfer_buffer.cc5
-rw-r--r--chromium/gpu/command_buffer/client/webgpu_implementation.cc56
-rw-r--r--chromium/gpu/command_buffer/client/webgpu_implementation.h9
-rw-r--r--chromium/gpu/command_buffer/client/webgpu_interface.h17
-rw-r--r--chromium/gpu/command_buffer/client/webgpu_interface_stub.cc6
-rw-r--r--chromium/gpu/command_buffer/client/webgpu_interface_stub.h4
-rw-r--r--chromium/gpu/command_buffer/common/gles2_cmd_format.h30
-rw-r--r--chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc4
-rw-r--r--chromium/gpu/command_buffer/common/swap_buffers_complete_params.h7
-rw-r--r--chromium/gpu/command_buffer/service/BUILD.gn4
-rw-r--r--chromium/gpu/command_buffer/service/DEPS10
-rw-r--r--chromium/gpu/command_buffer/service/abstract_texture_impl_shared_context_state.cc28
-rw-r--r--chromium/gpu/command_buffer/service/external_semaphore.cc2
-rw-r--r--chromium/gpu/command_buffer/service/external_semaphore_pool.cc5
-rw-r--r--chromium/gpu/command_buffer/service/external_vk_image_backing.cc53
-rw-r--r--chromium/gpu/command_buffer/service/external_vk_image_backing.h10
-rw-r--r--chromium/gpu/command_buffer/service/external_vk_image_factory.cc4
-rw-r--r--chromium/gpu/command_buffer/service/external_vk_image_factory.h5
-rw-r--r--chromium/gpu/command_buffer/service/external_vk_image_skia_representation.cc4
-rw-r--r--chromium/gpu/command_buffer/service/feature_info.cc206
-rw-r--r--chromium/gpu/command_buffer/service/gl_utils.cc8
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc15
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc67
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc48
-rw-r--r--chromium/gpu/command_buffer/service/gpu_fence_manager.cc7
-rw-r--r--chromium/gpu/command_buffer/service/gpu_fence_manager.h3
-rw-r--r--chromium/gpu/command_buffer/service/gpu_fence_manager_unittest.cc11
-rw-r--r--chromium/gpu/command_buffer/service/image_reader_gl_owner.cc7
-rw-r--r--chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc6
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder.cc1
-rw-r--r--chromium/gpu/command_buffer/service/shared_context_state.cc62
-rw-r--r--chromium/gpu/command_buffer/service/shared_context_state.h2
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc18
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_d3d.h14
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_egl_image.cc2
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc1
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc62
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.h4
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc68
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h11
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc118
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc3
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_gl_common.h2
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_gl_image.cc60
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_gl_image.h13
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_backing_gl_texture.cc37
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_factory.cc15
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_factory.h3
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_representation.cc14
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_representation.h17
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc23
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_representation_d3d.h19
-rw-r--r--chromium/gpu/command_buffer/service/shared_image_video.cc2
-rw-r--r--chromium/gpu/command_buffer/service/test_shared_image_backing.cc1
-rw-r--r--chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc7
-rw-r--r--chromium/gpu/command_buffer/service/wrapped_sk_image.cc17
-rw-r--r--chromium/gpu/command_buffer/service/wrapped_sk_image.h5
62 files changed, 1219 insertions, 539 deletions
diff --git a/chromium/gpu/command_buffer/client/gl_helper_scaling.cc b/chromium/gpu/command_buffer/client/gl_helper_scaling.cc
index a6ac94340fc..e35ccfa7947 100644
--- a/chromium/gpu/command_buffer/client/gl_helper_scaling.cc
+++ b/chromium/gpu/command_buffer/client/gl_helper_scaling.cc
@@ -523,33 +523,44 @@ class ScalerImpl : public GLHelper::ScalerInterface {
src_rect.size() == gfx::SizeF(result_size))
? GL_NEAREST
: GL_LINEAR;
- // Bind to the source texture and set the filitering and clamp to the edge,
- // as required by all shader programs.
- ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, src_texture);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- 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);
-
- // Prepare the shader program for drawing.
- ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
- gl_, scaler_helper_->vertex_attributes_buffer_);
- shader_program_->UseProgram(src_texture_size, src_rect, result_size,
- spec_.scale_x, spec_.flip_output,
- color_weights_);
-
- // Execute the draw.
- gl_->Viewport(0, 0, result_size.width(), result_size.height());
- const GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1};
- if (dest_texture_1 > 0) {
- DCHECK_LE(2, scaler_helper_->helper_->MaxDrawBuffers());
- gl_->DrawBuffersEXT(2, buffers);
- }
- gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- if (dest_texture_1 > 0) {
- // Set the draw buffers back to not disrupt external operations.
- gl_->DrawBuffersEXT(1, buffers);
+
+ // Set the active texture unit to 0 for the ScopedTextureBinder below, then
+ // restore the original value when done. (crbug.com/1103385)
+ GLint oldActiveTexture = 0;
+ gl_->GetIntegerv(GL_ACTIVE_TEXTURE, &oldActiveTexture);
+ gl_->ActiveTexture(GL_TEXTURE0);
+ {
+ // Bind to the source texture and set the filitering and clamp to the
+ // edge, as required by all shader programs.
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, src_texture);
+ gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ 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);
+
+ // Prepare the shader program for drawing.
+ ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
+ gl_, scaler_helper_->vertex_attributes_buffer_);
+ shader_program_->UseProgram(src_texture_size, src_rect, result_size,
+ spec_.scale_x, spec_.flip_output,
+ color_weights_);
+
+ // Execute the draw.
+ gl_->Viewport(0, 0, result_size.width(), result_size.height());
+ const GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0 + 1};
+ if (dest_texture_1 > 0) {
+ DCHECK_LE(2, scaler_helper_->helper_->MaxDrawBuffers());
+ gl_->DrawBuffersEXT(2, buffers);
+ }
+ gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ if (dest_texture_1 > 0) {
+ // Set the draw buffers back to not disrupt external operations.
+ gl_->DrawBuffersEXT(1, buffers);
+ }
+
+ // ScopedTextureBinder ends here, before restoring ActiveTexture state.
}
+ gl_->ActiveTexture(oldActiveTexture);
}
GLES2Interface* gl_;
diff --git a/chromium/gpu/command_buffer/client/gles2_implementation.cc b/chromium/gpu/command_buffer/client/gles2_implementation.cc
index 49d050e7e0d..e1611b999bb 100644
--- a/chromium/gpu/command_buffer/client/gles2_implementation.cc
+++ b/chromium/gpu/command_buffer/client/gles2_implementation.cc
@@ -143,6 +143,19 @@ bool IsReadbackUsage(GLenum usage) {
usage == GL_STATIC_READ;
}
+void UpdateProgramInfo(base::span<const uint8_t>& data,
+ ProgramInfoManager* manager,
+ ProgramInfoManager::ProgramInfoType type) {
+ DCHECK(data.size() > sizeof(cmds::GLES2ReturnProgramInfo));
+ const cmds::GLES2ReturnProgramInfo* return_program_info =
+ reinterpret_cast<const cmds::GLES2ReturnProgramInfo*>(data.data());
+ uint32_t program = return_program_info->program_client_id;
+ base::span<const int8_t> info(
+ reinterpret_cast<const int8_t*>(return_program_info->deserialized_buffer),
+ data.size() - sizeof(cmds::GLES2ReturnProgramInfo));
+ manager->UpdateProgramInfo(program, info, type);
+}
+
} // anonymous namespace
GLES2Implementation::GLStaticState::GLStaticState() = default;
@@ -448,7 +461,31 @@ void GLES2Implementation::OnSwapBufferPresented(
void GLES2Implementation::OnGpuControlReturnData(
base::span<const uint8_t> data) {
- NOTIMPLEMENTED();
+ DCHECK(data.size() > sizeof(cmds::GLES2ReturnDataHeader));
+ const cmds::GLES2ReturnDataHeader& gles2ReturnDataHeader =
+ *reinterpret_cast<const cmds::GLES2ReturnDataHeader*>(data.data());
+
+ switch (gles2ReturnDataHeader.return_data_type) {
+ case GLES2ReturnDataType::kES2ProgramInfo: {
+ UpdateProgramInfo(data, share_group_->program_info_manager(),
+ ProgramInfoManager::kES2);
+ } break;
+ case GLES2ReturnDataType::kES3UniformBlocks: {
+ UpdateProgramInfo(data, share_group_->program_info_manager(),
+ ProgramInfoManager::kES3UniformBlocks);
+ } break;
+ case GLES2ReturnDataType::kES3TransformFeedbackVaryings: {
+ UpdateProgramInfo(data, share_group_->program_info_manager(),
+ ProgramInfoManager::kES3TransformFeedbackVaryings);
+ } break;
+ case GLES2ReturnDataType::kES3Uniforms: {
+ UpdateProgramInfo(data, share_group_->program_info_manager(),
+ ProgramInfoManager::kES3Uniformsiv);
+ } break;
+
+ default:
+ NOTREACHED();
+ }
}
void GLES2Implementation::FreeSharedMemory(void* mem) {
@@ -723,11 +760,14 @@ GLboolean GLES2Implementation::IsEnablediOES(GLenum target, GLuint index) {
<< ")");
bool state = false;
typedef cmds::IsEnabled::Result Result;
- auto result = GetResultAs<Result>();
- *result = 0;
- helper_->IsEnablediOES(target, index, GetResultShmId(), result.offset());
- WaitForCmd();
- state = (*result) != 0;
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ *result = 0;
+ helper_->IsEnablediOES(target, index, GetResultShmId(), result.offset());
+ WaitForCmd();
+ state = (*result) != 0;
+ }
GPU_CLIENT_LOG("returned " << state);
CheckGLError();
@@ -4383,35 +4423,38 @@ void GLES2Implementation::GetShaderPrecisionFormat(GLenum shadertype,
<< static_cast<const void*>(precision) << ", ");
TRACE_EVENT0("gpu", "GLES2::GetShaderPrecisionFormat");
typedef cmds::GetShaderPrecisionFormat::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
-
- GLStaticState::ShaderPrecisionKey key(shadertype, precisiontype);
- GLStaticState::ShaderPrecisionMap::iterator i =
- static_state_.shader_precisions.find(key);
- if (i != static_state_.shader_precisions.end()) {
- *result = i->second;
- } else {
- result->success = false;
- helper_->GetShaderPrecisionFormat(shadertype, precisiontype,
- GetResultShmId(), result.offset());
- WaitForCmd();
- if (result->success)
- static_state_.shader_precisions[key] = *result;
- }
-
- if (result->success) {
- if (range) {
- range[0] = result->min_range;
- range[1] = result->max_range;
- GPU_CLIENT_LOG(" min_range: " << range[0]);
- GPU_CLIENT_LOG(" min_range: " << range[1]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- if (precision) {
- precision[0] = result->precision;
- GPU_CLIENT_LOG(" min_range: " << precision[0]);
+
+ GLStaticState::ShaderPrecisionKey key(shadertype, precisiontype);
+ GLStaticState::ShaderPrecisionMap::iterator i =
+ static_state_.shader_precisions.find(key);
+ if (i != static_state_.shader_precisions.end()) {
+ *result = i->second;
+ } else {
+ result->success = false;
+ helper_->GetShaderPrecisionFormat(shadertype, precisiontype,
+ GetResultShmId(), result.offset());
+ WaitForCmd();
+ if (result->success)
+ static_state_.shader_precisions[key] = *result;
+ }
+
+ if (result->success) {
+ if (range) {
+ range[0] = result->min_range;
+ range[1] = result->max_range;
+ GPU_CLIENT_LOG(" min_range: " << range[0]);
+ GPU_CLIENT_LOG(" min_range: " << range[1]);
+ }
+ if (precision) {
+ precision[0] = result->precision;
+ GPU_CLIENT_LOG(" min_range: " << precision[0]);
+ }
}
}
CheckGLError();
@@ -4570,19 +4613,22 @@ void GLES2Implementation::GetUniformfv(GLuint program,
<< ")");
TRACE_EVENT0("gpu", "GLES2::GetUniformfv");
typedef cmds::GetUniformfv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetUniformfv(program, location, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetUniformfv(program, location, GetResultShmId(), result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -4595,19 +4641,22 @@ void GLES2Implementation::GetUniformiv(GLuint program,
<< ")");
TRACE_EVENT0("gpu", "GLES2::GetUniformiv");
typedef cmds::GetUniformiv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetUniformiv(program, location, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetUniformiv(program, location, GetResultShmId(), result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -4620,19 +4669,23 @@ void GLES2Implementation::GetUniformuiv(GLuint program,
<< static_cast<const void*>(params) << ")");
TRACE_EVENT0("gpu", "GLES2::GetUniformuiv");
typedef cmds::GetUniformuiv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetUniformuiv(program, location, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetUniformuiv(program, location, GetResultShmId(),
+ result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -5473,19 +5526,22 @@ void GLES2Implementation::GetVertexAttribfv(GLuint index,
}
TRACE_EVENT0("gpu", "GLES2::GetVertexAttribfv");
typedef cmds::GetVertexAttribfv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetVertexAttribfv(index, pname, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetVertexAttribfv(index, pname, GetResultShmId(), result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -5503,19 +5559,22 @@ void GLES2Implementation::GetVertexAttribiv(GLuint index,
}
TRACE_EVENT0("gpu", "GLES2::GetVertexAttribiv");
typedef cmds::GetVertexAttribiv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetVertexAttribiv(index, pname, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetVertexAttribiv(index, pname, GetResultShmId(), result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -5533,19 +5592,23 @@ void GLES2Implementation::GetVertexAttribIiv(GLuint index,
}
TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIiv");
typedef cmds::GetVertexAttribiv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetVertexAttribIiv(index, pname, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetVertexAttribIiv(index, pname, GetResultShmId(),
+ result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -5563,19 +5626,23 @@ void GLES2Implementation::GetVertexAttribIuiv(GLuint index,
}
TRACE_EVENT0("gpu", "GLES2::GetVertexAttribIuiv");
typedef cmds::GetVertexAttribiv::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetVertexAttribIuiv(index, pname, GetResultShmId(), result.offset());
- WaitForCmd();
- result->CopyResult(params);
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- });
+ result->SetNumResults(0);
+ helper_->GetVertexAttribIuiv(index, pname, GetResultShmId(),
+ result.offset());
+ WaitForCmd();
+ result->CopyResult(params);
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ }
CheckGLError();
}
@@ -7331,18 +7398,23 @@ GLenum GLES2Implementation::ClientWaitSync(GLsync sync,
GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClientWaitSync(" << sync << ", "
<< flags << ", " << timeout << ")");
typedef cmds::ClientWaitSync::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- SetGLError(GL_OUT_OF_MEMORY, "ClientWaitSync", "");
- return GL_WAIT_FAILED;
+ // Limit scope of result to avoid overlap with CheckGLError()
+ Result localResult;
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ SetGLError(GL_OUT_OF_MEMORY, "ClientWaitSync", "");
+ return GL_WAIT_FAILED;
+ }
+ *result = GL_WAIT_FAILED;
+ helper_->ClientWaitSync(ToGLuint(sync), flags, timeout, GetResultShmId(),
+ result.offset());
+ WaitForCmd();
+ localResult = *result;
+ GPU_CLIENT_LOG("returned " << localResult);
}
- *result = GL_WAIT_FAILED;
- helper_->ClientWaitSync(ToGLuint(sync), flags, timeout, GetResultShmId(),
- result.offset());
- WaitForCmd();
- GPU_CLIENT_LOG("returned " << *result);
CheckGLError();
- return *result;
+ return localResult;
}
void GLES2Implementation::CopyBufferSubData(GLenum readtarget,
@@ -7406,26 +7478,29 @@ void GLES2Implementation::GetInternalformativ(GLenum target,
return;
}
typedef cmds::GetInternalformativ::Result Result;
- auto result = GetResultAs<Result>();
- if (!result) {
- return;
- }
- result->SetNumResults(0);
- helper_->GetInternalformativ(target, format, pname, GetResultShmId(),
- result.offset());
- WaitForCmd();
- GPU_CLIENT_LOG_CODE_BLOCK({
- for (int32_t i = 0; i < result->GetNumResults(); ++i) {
- GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
- }
- });
- if (buf_size > 0 && params) {
- GLint* data = result->GetData();
- if (buf_size >= result->GetNumResults()) {
- buf_size = result->GetNumResults();
+ // Limit scope of result to avoid overlap with CheckGLError()
+ {
+ auto result = GetResultAs<Result>();
+ if (!result) {
+ return;
}
- for (GLsizei ii = 0; ii < buf_size; ++ii) {
- params[ii] = data[ii];
+ result->SetNumResults(0);
+ helper_->GetInternalformativ(target, format, pname, GetResultShmId(),
+ result.offset());
+ WaitForCmd();
+ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (int32_t i = 0; i < result->GetNumResults(); ++i) {
+ GPU_CLIENT_LOG(" " << i << ": " << result->GetData()[i]);
+ }
+ });
+ if (buf_size > 0 && params) {
+ GLint* data = result->GetData();
+ if (buf_size >= result->GetNumResults()) {
+ buf_size = result->GetNumResults();
+ }
+ for (GLsizei ii = 0; ii < buf_size; ++ii) {
+ params[ii] = data[ii];
+ }
}
}
CheckGLError();
diff --git a/chromium/gpu/command_buffer/client/program_info_manager.cc b/chromium/gpu/command_buffer/client/program_info_manager.cc
index 5e3299ed9d2..a3f5eb65f2e 100644
--- a/chromium/gpu/command_buffer/client/program_info_manager.cc
+++ b/chromium/gpu/command_buffer/client/program_info_manager.cc
@@ -10,7 +10,7 @@
namespace {
template <typename T>
-static T LocalGetAs(const std::vector<int8_t>& data,
+static T LocalGetAs(base::span<const int8_t> data,
uint32_t offset,
size_t size) {
const int8_t* p = data.data() + offset;
@@ -358,7 +358,7 @@ bool ProgramInfoManager::Program::GetUniformsiv(
return false;
}
-void ProgramInfoManager::Program::UpdateES2(const std::vector<int8_t>& result) {
+void ProgramInfoManager::Program::UpdateES2(base::span<const int8_t> result) {
if (cached_es2_) {
return;
}
@@ -414,7 +414,7 @@ void ProgramInfoManager::Program::UpdateES2(const std::vector<int8_t>& result) {
}
void ProgramInfoManager::Program::UpdateES3UniformBlocks(
- const std::vector<int8_t>& result) {
+ base::span<const int8_t> result) {
if (cached_es3_uniform_blocks_) {
return;
}
@@ -485,7 +485,7 @@ void ProgramInfoManager::Program::UpdateES3UniformBlocks(
}
void ProgramInfoManager::Program::UpdateES3Uniformsiv(
- const std::vector<int8_t>& result) {
+ base::span<const int8_t> result) {
if (cached_es3_uniformsiv_) {
return;
}
@@ -527,7 +527,7 @@ void ProgramInfoManager::Program::UpdateES3Uniformsiv(
}
void ProgramInfoManager::Program::UpdateES3TransformFeedbackVaryings(
- const std::vector<int8_t>& result) {
+ base::span<const int8_t> result) {
if (cached_es3_transform_feedback_varyings_) {
return;
}
@@ -1059,6 +1059,37 @@ GLint ProgramInfoManager::GetProgramResourceLocation(
return gl->GetProgramResourceLocationHelper(program, program_interface, name);
}
+void ProgramInfoManager::UpdateProgramInfo(GLuint program,
+ base::span<const int8_t> data,
+ ProgramInfoType type) {
+ base::AutoLock auto_lock(lock_);
+ ProgramInfoMap::iterator it = program_infos_.find(program);
+ // It's possible that the program has been deleted already. Imagine the code
+ // snippet below:
+ // ...
+ // gl.linkProgram(program);
+ // gl.deleteProgram(program);
+ // ...
+ if (it == program_infos_.end())
+ return;
+ Program* info = &it->second;
+ switch (type) {
+ case kES2:
+ info->UpdateES2(data);
+ break;
+ case kES3UniformBlocks:
+ info->UpdateES3UniformBlocks(data);
+ break;
+ case kES3TransformFeedbackVaryings:
+ info->UpdateES3TransformFeedbackVaryings(data);
+ break;
+ case kES3Uniformsiv:
+ info->UpdateES3Uniformsiv(data);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
} // namespace gles2
} // namespace gpu
-
diff --git a/chromium/gpu/command_buffer/client/program_info_manager.h b/chromium/gpu/command_buffer/client/program_info_manager.h
index ee39eecb8e1..fb45541986d 100644
--- a/chromium/gpu/command_buffer/client/program_info_manager.h
+++ b/chromium/gpu/command_buffer/client/program_info_manager.h
@@ -104,6 +104,18 @@ class GLES2_IMPL_EXPORT ProgramInfoManager {
GLES2Implementation* gl, GLuint program, GLenum program_interface,
const char* name);
+ enum ProgramInfoType {
+ kES2,
+ kES3UniformBlocks,
+ kES3TransformFeedbackVaryings,
+ kES3Uniformsiv,
+ kNone,
+ };
+
+ void UpdateProgramInfo(GLuint program,
+ base::span<const int8_t> result,
+ ProgramInfoType type);
+
private:
friend class ProgramInfoManagerTest;
@@ -114,14 +126,6 @@ class GLES2_IMPL_EXPORT ProgramInfoManager {
FRIEND_TEST_ALL_PREFIXES(ProgramInfoManagerTest,
GetActiveUniformsivCached);
- enum ProgramInfoType {
- kES2,
- kES3UniformBlocks,
- kES3TransformFeedbackVaryings,
- kES3Uniformsiv,
- kNone,
- };
-
// Need GLES2_IMPL_EXPORT for tests.
class GLES2_IMPL_EXPORT Program {
public:
@@ -213,16 +217,16 @@ class GLES2_IMPL_EXPORT ProgramInfoManager {
GLuint index) const;
// Updates the ES2 only program info after a successful link.
- void UpdateES2(const std::vector<int8_t>& result);
+ void UpdateES2(base::span<const int8_t> result);
// Updates the ES3 UniformBlock info after a successful link.
- void UpdateES3UniformBlocks(const std::vector<int8_t>& result);
+ void UpdateES3UniformBlocks(base::span<const int8_t> result);
// Updates the ES3 Uniformsiv info after a successful link.
- void UpdateES3Uniformsiv(const std::vector<int8_t>& result);
+ void UpdateES3Uniformsiv(base::span<const int8_t> result);
// Updates the ES3 TransformFeedbackVaryings info after a successful link.
- void UpdateES3TransformFeedbackVaryings(const std::vector<int8_t>& result);
+ void UpdateES3TransformFeedbackVaryings(base::span<const int8_t> result);
bool IsCached(ProgramInfoType type) const;
diff --git a/chromium/gpu/command_buffer/client/shared_image_interface.h b/chromium/gpu/command_buffer/client/shared_image_interface.h
index 8c33e90124c..0f11fbbeeba 100644
--- a/chromium/gpu/command_buffer/client/shared_image_interface.h
+++ b/chromium/gpu/command_buffer/client/shared_image_interface.h
@@ -169,10 +169,15 @@ class GPU_EXPORT SharedImageInterface {
// |buffer_collection_id| and |buffer_index| fields in NativePixmapHandle,
// wrapping it in GpuMemoryBufferHandle and then creating GpuMemoryBuffer from
// that handle.
- virtual void RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
- zx::channel token,
- gfx::BufferFormat format,
- gfx::BufferUsage usage) = 0;
+ // If |register_with_image_pipe| field is set, a new ImagePipe is created and
+ // |token| is duped to collect ImagePipe constraints. SysmemBufferCollection
+ // is then available for direct presentation.
+ virtual void RegisterSysmemBufferCollection(
+ gfx::SysmemBufferCollectionId id,
+ zx::channel token,
+ gfx::BufferFormat format,
+ gfx::BufferUsage usage,
+ bool register_with_image_pipe) = 0;
virtual void ReleaseSysmemBufferCollection(
gfx::SysmemBufferCollectionId id) = 0;
diff --git a/chromium/gpu/command_buffer/client/transfer_buffer.cc b/chromium/gpu/command_buffer/client/transfer_buffer.cc
index e010ddbdeb0..4b55c05872e 100644
--- a/chromium/gpu/command_buffer/client/transfer_buffer.cc
+++ b/chromium/gpu/command_buffer/client/transfer_buffer.cc
@@ -61,6 +61,11 @@ void TransferBuffer::Free() {
TRACE_EVENT0("gpu", "TransferBuffer::Free");
helper_->OrderingBarrier();
helper_->command_buffer()->DestroyTransferBuffer(buffer_id_);
+ if (!HaveBuffer()) {
+ // The above may call this function reentrantly. If the buffer was
+ // already freed, then our work is done.
+ return;
+ }
buffer_id_ = -1;
buffer_ = nullptr;
result_buffer_ = nullptr;
diff --git a/chromium/gpu/command_buffer/client/webgpu_implementation.cc b/chromium/gpu/command_buffer/client/webgpu_implementation.cc
index 8fd0df66783..c558e420ed0 100644
--- a/chromium/gpu/command_buffer/client/webgpu_implementation.cc
+++ b/chromium/gpu/command_buffer/client/webgpu_implementation.cc
@@ -141,12 +141,20 @@ bool WebGPUCommandSerializer::Flush() {
c2s_buffer_.offset(), c2s_put_offset_);
c2s_put_offset_ = 0;
c2s_buffer_.Release();
+ client_awaiting_flush_ = false;
}
memory_transfer_service_->FreeHandlesPendingToken(helper_->InsertToken());
return true;
}
+void WebGPUCommandSerializer::SetClientAwaitingFlush(bool awaiting_flush) {
+ // If awaiting_flush is true, but the c2s_buffer_ is invalid (empty), that
+ // means the last command right before this caused a flush. Another flush is
+ // not needed.
+ client_awaiting_flush_ = awaiting_flush && c2s_buffer_.valid();
+}
+
void WebGPUCommandSerializer::HandleGpuControlLostContext() {
// Immediately forget pending commands.
c2s_buffer_.Discard();
@@ -572,6 +580,54 @@ void WebGPUImplementation::FlushCommands() {
helper_->Flush();
}
+void WebGPUImplementation::FlushCommands(DawnDeviceClientID device_client_id) {
+#if BUILDFLAG(USE_DAWN)
+ WebGPUCommandSerializer* command_serializer =
+ GetCommandSerializerWithDeviceClientID(device_client_id);
+ DCHECK(command_serializer);
+ command_serializer->Flush();
+ helper_->Flush();
+#endif
+}
+
+void WebGPUImplementation::EnsureAwaitingFlush(
+ DawnDeviceClientID device_client_id,
+ bool* needs_flush) {
+#if BUILDFLAG(USE_DAWN)
+ WebGPUCommandSerializer* command_serializer =
+ GetCommandSerializerWithDeviceClientID(device_client_id);
+ DCHECK(command_serializer);
+
+ // If there is already a flush waiting, we don't need to flush.
+ // We only want to set |needs_flush| on state transition from
+ // false -> true.
+ if (command_serializer->ClientAwaitingFlush()) {
+ *needs_flush = false;
+ return;
+ }
+
+ // Set the state to waiting for flush, and then write |needs_flush|.
+ // Could still be false if there's no data to flush.
+ command_serializer->SetClientAwaitingFlush(true);
+ *needs_flush = command_serializer->ClientAwaitingFlush();
+#else
+ *needs_flush = false;
+#endif
+}
+
+void WebGPUImplementation::FlushAwaitingCommands(
+ DawnDeviceClientID device_client_id) {
+#if BUILDFLAG(USE_DAWN)
+ WebGPUCommandSerializer* command_serializer =
+ GetCommandSerializerWithDeviceClientID(device_client_id);
+ DCHECK(command_serializer);
+ if (command_serializer->ClientAwaitingFlush()) {
+ command_serializer->Flush();
+ helper_->Flush();
+ }
+#endif
+}
+
WGPUDevice WebGPUImplementation::GetDevice(
DawnDeviceClientID device_client_id) {
#if BUILDFLAG(USE_DAWN)
diff --git a/chromium/gpu/command_buffer/client/webgpu_implementation.h b/chromium/gpu/command_buffer/client/webgpu_implementation.h
index f3fec66d06f..c1fc35bd8c8 100644
--- a/chromium/gpu/command_buffer/client/webgpu_implementation.h
+++ b/chromium/gpu/command_buffer/client/webgpu_implementation.h
@@ -47,6 +47,9 @@ class WebGPUCommandSerializer final : public dawn_wire::CommandSerializer {
void* GetCmdSpace(size_t size) final;
bool Flush() final;
+ void SetClientAwaitingFlush(bool awaiting_flush);
+ bool ClientAwaitingFlush() const { return client_awaiting_flush_; }
+
// Called upon context lost.
void HandleGpuControlLostContext();
@@ -66,6 +69,8 @@ class WebGPUCommandSerializer final : public dawn_wire::CommandSerializer {
uint32_t c2s_put_offset_ = 0;
std::unique_ptr<TransferBuffer> c2s_transfer_buffer_;
ScopedTransferBufferPtr c2s_buffer_;
+
+ bool client_awaiting_flush_ = false;
};
#endif
@@ -153,6 +158,10 @@ class WEBGPU_EXPORT WebGPUImplementation final : public WebGPUInterface,
// WebGPUInterface implementation
const DawnProcTable& GetProcs() const override;
void FlushCommands() override;
+ void FlushCommands(DawnDeviceClientID device_client_id) override;
+ void EnsureAwaitingFlush(DawnDeviceClientID device_client_id,
+ bool* needs_flush) override;
+ void FlushAwaitingCommands(DawnDeviceClientID device_client_id) override;
WGPUDevice GetDevice(DawnDeviceClientID device_client_id) override;
ReservedTexture ReserveTexture(DawnDeviceClientID device_client_id) override;
bool RequestAdapterAsync(
diff --git a/chromium/gpu/command_buffer/client/webgpu_interface.h b/chromium/gpu/command_buffer/client/webgpu_interface.h
index 56138e7db67..e09175e998f 100644
--- a/chromium/gpu/command_buffer/client/webgpu_interface.h
+++ b/chromium/gpu/command_buffer/client/webgpu_interface.h
@@ -28,7 +28,24 @@ class WebGPUInterface : public InterfaceBase {
virtual ~WebGPUInterface() {}
virtual const DawnProcTable& GetProcs() const = 0;
+
+ // Flush all commands.
virtual void FlushCommands() = 0;
+
+ // Flush all commands on the device client.
+ virtual void FlushCommands(DawnDeviceClientID device_client_id) = 0;
+
+ // Ensure the awaiting flush flag is set on the device client. Returns false
+ // if a flush has already been indicated, or a flush is not needed (there may
+ // be no commands to flush). Returns true if the caller should schedule a
+ // flush.
+ virtual void EnsureAwaitingFlush(DawnDeviceClientID device_client_id,
+ bool* needs_flush) = 0;
+
+ // If the awaiting flush flag is set, flushes commands. Otherwise, does
+ // nothing.
+ virtual void FlushAwaitingCommands(DawnDeviceClientID device_client_id) = 0;
+
virtual WGPUDevice GetDevice(DawnDeviceClientID device_client_id) = 0;
virtual ReservedTexture ReserveTexture(
DawnDeviceClientID device_client_id) = 0;
diff --git a/chromium/gpu/command_buffer/client/webgpu_interface_stub.cc b/chromium/gpu/command_buffer/client/webgpu_interface_stub.cc
index c06f7d21c80..1ace9f20064 100644
--- a/chromium/gpu/command_buffer/client/webgpu_interface_stub.cc
+++ b/chromium/gpu/command_buffer/client/webgpu_interface_stub.cc
@@ -23,6 +23,12 @@ const DawnProcTable& WebGPUInterfaceStub::GetProcs() const {
return null_procs_;
}
void WebGPUInterfaceStub::FlushCommands() {}
+void WebGPUInterfaceStub::FlushCommands(DawnDeviceClientID device_client_id) {}
+void WebGPUInterfaceStub::EnsureAwaitingFlush(
+ DawnDeviceClientID device_client_id,
+ bool* needs_flush) {}
+void WebGPUInterfaceStub::FlushAwaitingCommands(
+ DawnDeviceClientID device_client_id) {}
WGPUDevice WebGPUInterfaceStub::GetDevice(DawnDeviceClientID device_client_id) {
return nullptr;
}
diff --git a/chromium/gpu/command_buffer/client/webgpu_interface_stub.h b/chromium/gpu/command_buffer/client/webgpu_interface_stub.h
index 1b99eef4cbd..22a9112fe67 100644
--- a/chromium/gpu/command_buffer/client/webgpu_interface_stub.h
+++ b/chromium/gpu/command_buffer/client/webgpu_interface_stub.h
@@ -25,6 +25,10 @@ class WebGPUInterfaceStub : public WebGPUInterface {
// WebGPUInterface implementation
const DawnProcTable& GetProcs() const override;
void FlushCommands() override;
+ void FlushCommands(DawnDeviceClientID device_client_id) override;
+ void EnsureAwaitingFlush(DawnDeviceClientID device_client_id,
+ bool* needs_flush) override;
+ void FlushAwaitingCommands(DawnDeviceClientID device_client_id) override;
WGPUDevice GetDevice(DawnDeviceClientID device_client_id) override;
ReservedTexture ReserveTexture(DawnDeviceClientID device_client_id) override;
bool RequestAdapterAsync(
diff --git a/chromium/gpu/command_buffer/common/gles2_cmd_format.h b/chromium/gpu/command_buffer/common/gles2_cmd_format.h
index ecb2dc4a03d..188a21224ea 100644
--- a/chromium/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/chromium/gpu/command_buffer/common/gles2_cmd_format.h
@@ -226,10 +226,40 @@ static_assert(sizeof(UniformBlocksHeader) == 4,
static_assert(offsetof(UniformBlocksHeader, num_uniform_blocks) == 0,
"offset of UniformBlocksHeader.num_uniform_blocks should be 0");
+enum class GLES2ReturnDataType : uint32_t {
+ kES2ProgramInfo,
+ kES3UniformBlocks,
+ kES3TransformFeedbackVaryings,
+ kES3Uniforms
+};
+
namespace cmds {
#include "gpu/command_buffer/common/gles2_cmd_format_autogen.h"
+struct GLES2ReturnDataHeader {
+ GLES2ReturnDataType return_data_type;
+};
+static_assert(sizeof(GLES2ReturnDataHeader) == 4,
+ "size of GLES2ReturnDataHeader should be 4");
+static_assert(offsetof(GLES2ReturnDataHeader, return_data_type) == 0,
+ "The offset of return_data_type should be 0");
+
+struct GLES2ReturnProgramInfo {
+ GLES2ReturnDataHeader return_data_header = {
+ GLES2ReturnDataType::kES2ProgramInfo};
+ uint32_t program_client_id = 0;
+ char deserialized_buffer[];
+};
+static_assert(sizeof(GLES2ReturnProgramInfo) == 8,
+ "size of GLES2ReturnProgramInfo should be 8");
+static_assert(offsetof(GLES2ReturnProgramInfo, return_data_header) == 0,
+ "The offset of return_data_header should be 0");
+static_assert(offsetof(GLES2ReturnProgramInfo, program_client_id) == 4,
+ "The offset of program_client_id should be 4");
+static_assert(offsetof(GLES2ReturnProgramInfo, deserialized_buffer) == 8,
+ "The offset of deserialized_buffer should be 8");
+
#pragma pack(pop)
} // namespace cmd
diff --git a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc
index c268bc166f5..388de9f4003 100644
--- a/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc
+++ b/chromium/gpu/command_buffer/common/gpu_memory_buffer_support.cc
@@ -55,7 +55,7 @@ bool IsImageSizeValidForGpuMemoryBufferFormat(const gfx::Size& size,
uint32_t GetPlatformSpecificTextureTarget() {
#if defined(OS_MAC)
return macos_specific_texture_target;
-#elif defined(OS_ANDROID) || defined(OS_LINUX)
+#elif defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS)
return GL_TEXTURE_EXTERNAL_OES;
#elif defined(OS_WIN) || defined(OS_FUCHSIA)
return GL_TEXTURE_2D;
@@ -85,7 +85,7 @@ GPU_EXPORT uint32_t GetBufferTextureTarget(gfx::BufferUsage usage,
GPU_EXPORT bool NativeBufferNeedsPlatformSpecificTextureTarget(
gfx::BufferFormat format) {
-#if defined(USE_OZONE) || defined(OS_LINUX)
+#if defined(USE_OZONE) || defined(OS_LINUX) || defined(OS_CHROMEOS)
// Always use GL_TEXTURE_2D as the target for RGB textures.
// https://crbug.com/916728
if (format == gfx::BufferFormat::R_8 || format == gfx::BufferFormat::RG_88 ||
diff --git a/chromium/gpu/command_buffer/common/swap_buffers_complete_params.h b/chromium/gpu/command_buffer/common/swap_buffers_complete_params.h
index 766c0bcb20b..252891900cf 100644
--- a/chromium/gpu/command_buffer/common/swap_buffers_complete_params.h
+++ b/chromium/gpu/command_buffer/common/swap_buffers_complete_params.h
@@ -5,7 +5,10 @@
#ifndef GPU_COMMAND_BUFFER_COMMON_SWAP_BUFFERS_COMPLETE_PARAMS_H_
#define GPU_COMMAND_BUFFER_COMMON_SWAP_BUFFERS_COMPLETE_PARAMS_H_
+#include <vector>
+
#include "base/optional.h"
+#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/texture_in_use_response.h"
#include "ui/gfx/ca_layer_params.h"
#include "ui/gfx/geometry/rect.h"
@@ -31,9 +34,13 @@ struct GPU_EXPORT SwapBuffersCompleteParams {
// Used only on macOS, for coordinating IOSurface reuse with the system
// WindowServer.
gpu::TextureInUseResponses texture_in_use_responses;
+
// Used only on macOS, to allow the browser hosted NSWindow to display
// content populated in the GPU process.
gfx::CALayerParams ca_layer_params;
+
+ // Used only on macOS, for released overlays with SkiaRenderer.
+ std::vector<Mailbox> released_overlays;
};
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/BUILD.gn b/chromium/gpu/command_buffer/service/BUILD.gn
index 7bdea113f63..56cb7346a69 100644
--- a/chromium/gpu/command_buffer/service/BUILD.gn
+++ b/chromium/gpu/command_buffer/service/BUILD.gn
@@ -448,7 +448,7 @@ target(link_target_type, "gles2_sources") {
"texture_owner.h",
]
- deps += [ "//media/base/android:android" ]
+ deps += [ "//base" ]
# TODO(cblume): http://crbug.com/911313
# Abstract out the platform specific defines. Right now we need the android
@@ -515,8 +515,6 @@ if (is_android) {
":gles2",
"//base/test:test_support",
"//gpu:test_support",
- "//media/base:base",
- "//media/base/android:android",
"//testing/gmock",
"//testing/gtest",
"//ui/gl",
diff --git a/chromium/gpu/command_buffer/service/DEPS b/chromium/gpu/command_buffer/service/DEPS
index ced2955f1ab..ff50b4a7bcd 100644
--- a/chromium/gpu/command_buffer/service/DEPS
+++ b/chromium/gpu/command_buffer/service/DEPS
@@ -10,13 +10,3 @@ include_rules = [
"+components/viz/common/resources/resource_format_utils.h",
"+components/viz/common/resources/resource_sizes.h",
]
-
-specific_include_rules = {
- "image_reader_gl_owner_unittest\.cc": [
- "+media/base/media_switches.h",
- "+media/base/android/media_codec_util.h",
- ],
- "image_reader_gl_owner\.cc": [
- "+media/base/android/media_codec_util.h",
- ],
-}
diff --git a/chromium/gpu/command_buffer/service/abstract_texture_impl_shared_context_state.cc b/chromium/gpu/command_buffer/service/abstract_texture_impl_shared_context_state.cc
index 803eb3bd0ec..f14ff3adec4 100644
--- a/chromium/gpu/command_buffer/service/abstract_texture_impl_shared_context_state.cc
+++ b/chromium/gpu/command_buffer/service/abstract_texture_impl_shared_context_state.cc
@@ -58,22 +58,23 @@ AbstractTextureImplOnSharedContext::AbstractTextureImplOnSharedContext(
}
AbstractTextureImplOnSharedContext::~AbstractTextureImplOnSharedContext() {
+ bool have_context = true;
+ base::Optional<ui::ScopedMakeCurrent> scoped_make_current;
if (cleanup_cb_)
std::move(cleanup_cb_).Run(this);
// If the shared context is lost, |shared_context_state_| will be null.
if (!shared_context_state_) {
- texture_->RemoveLightweightRef(false);
+ have_context = false;
} else {
- base::Optional<ui::ScopedMakeCurrent> scoped_make_current;
if (!shared_context_state_->IsCurrent(nullptr)) {
scoped_make_current.emplace(shared_context_state_->context(),
shared_context_state_->surface());
+ have_context = scoped_make_current->IsContextCurrent();
}
- texture_->RemoveLightweightRef(true);
shared_context_state_->RemoveContextLostObserver(this);
}
- texture_ = nullptr;
+ texture_->RemoveLightweightRef(have_context);
}
TextureBase* AbstractTextureImplOnSharedContext::GetTextureBase() const {
@@ -154,14 +155,10 @@ AbstractTextureImplOnSharedContextPassthrough::
AbstractTextureImplOnSharedContextPassthrough::
~AbstractTextureImplOnSharedContextPassthrough() {
+ base::Optional<ui::ScopedMakeCurrent> scoped_make_current;
if (cleanup_cb_)
std::move(cleanup_cb_).Run(this);
- // Save the current context and make it current again after deleting the
- // |texture_|.
- scoped_refptr<gl::GLContext> previous_context = gl::GLContext::GetCurrent();
- scoped_refptr<gl::GLSurface> previous_surface = gl::GLSurface::GetCurrent();
-
// If the shared context is lost, |shared_context_state_| will be null and the
// |texture_| is already marked to have lost its context.
if (shared_context_state_) {
@@ -170,16 +167,17 @@ AbstractTextureImplOnSharedContextPassthrough::
// destructor is not guaranteed to be called on the context on which the
// |texture_| was created.
if (!shared_context_state_->IsCurrent(nullptr)) {
- shared_context_state_->MakeCurrent(shared_context_state_->surface(),
- true /* needs_gl */);
+ scoped_make_current.emplace(shared_context_state_->context(),
+ shared_context_state_->surface());
+
+ // If |shared_context_state_|'s context is not current, then mark context
+ // lost for the |texture_|.
+ if (!scoped_make_current->IsContextCurrent())
+ texture_->MarkContextLost();
}
shared_context_state_->RemoveContextLostObserver(this);
}
texture_.reset();
-
- // Make the previous context current again.
- if (!previous_context->IsCurrent(previous_surface.get()))
- previous_context->MakeCurrent(previous_surface.get());
}
TextureBase* AbstractTextureImplOnSharedContextPassthrough::GetTextureBase()
diff --git a/chromium/gpu/command_buffer/service/external_semaphore.cc b/chromium/gpu/command_buffer/service/external_semaphore.cc
index 8bfe986f1f8..d51d00bd0d8 100644
--- a/chromium/gpu/command_buffer/service/external_semaphore.cc
+++ b/chromium/gpu/command_buffer/service/external_semaphore.cc
@@ -39,7 +39,7 @@ GLuint ImportSemaphoreHandleToGLSemaphore(SemaphoreHandle handle) {
},
base::Time::Now()));
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
if (handle.vk_handle_type() !=
VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
DLOG(ERROR) << "Importing semaphore handle of unexpected type:"
diff --git a/chromium/gpu/command_buffer/service/external_semaphore_pool.cc b/chromium/gpu/command_buffer/service/external_semaphore_pool.cc
index 2d8af08c456..e4a8180ab1e 100644
--- a/chromium/gpu/command_buffer/service/external_semaphore_pool.cc
+++ b/chromium/gpu/command_buffer/service/external_semaphore_pool.cc
@@ -15,11 +15,14 @@
namespace gpu {
namespace {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_FUCHSIA)
// On Android, semaphores are created with handle type
// VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT. With this handle type,
// the semaphore will not be reset to un-signalled state after waiting,
// so semaphores cannot be reused on Android.
+// On Fuchsia semaphores are passed to scenic as zx::event. Scenic doesn't reset
+// them after waiting, so they would have to be reset explicitly to be reused.
+// OTOH new semaphores are cheap, so reuse doesn't provide significant benefits.
constexpr size_t kMaxSemaphoresInPool = 0;
#else
constexpr size_t kMaxSemaphoresInPool = 16;
diff --git a/chromium/gpu/command_buffer/service/external_vk_image_backing.cc b/chromium/gpu/command_buffer/service/external_vk_image_backing.cc
index 191c0dd104d..263c79e9986 100644
--- a/chromium/gpu/command_buffer/service/external_vk_image_backing.cc
+++ b/chromium/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -29,7 +29,7 @@
#include "ui/gl/gl_version_info.h"
#include "ui/gl/scoped_binders.h"
-#if defined(OS_LINUX) && BUILDFLAG(USE_DAWN)
+#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && BUILDFLAG(USE_DAWN)
#include "gpu/command_buffer/service/external_vk_image_dawn_representation.h"
#endif
@@ -127,8 +127,9 @@ bool UseSeparateGLTexture(SharedContextState* context_state,
if (format != viz::ResourceFormat::BGRA_8888)
return false;
- const auto* version_info = context_state->real_context()->GetVersionInfo();
- const auto& ext = gl::g_current_gl_driver->ext;
+ auto* gl_context = context_state->real_context();
+ const auto* version_info = gl_context->GetVersionInfo();
+ const auto& ext = gl_context->GetCurrentGL()->Driver->ext;
if (!ext.b_GL_EXT_texture_format_BGRA8888)
return true;
@@ -166,7 +167,7 @@ void WaitSemaphoresOnGrContext(GrDirectContext* gr_context,
// static
std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create(
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
VulkanCommandPool* command_pool,
const Mailbox& mailbox,
viz::ResourceFormat format,
@@ -206,7 +207,7 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create(
// Must request all available image usage flags if aliasing GL texture. This
// is a spec requirement per EXT_memory_object. However, if
// ANGLE_memory_object_flags is supported, usage flags can be arbitrary.
- if (UseMinimalUsageFlags(context_state)) {
+ if (UseMinimalUsageFlags(context_state.get())) {
// The following additional usage flags are provided for ANGLE:
//
// - TRANSFER_SRC: Used for copies from this image.
@@ -247,10 +248,11 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create(
if (!image)
return nullptr;
- bool use_separate_gl_texture = UseSeparateGLTexture(context_state, format);
+ bool use_separate_gl_texture =
+ UseSeparateGLTexture(context_state.get(), format);
auto backing = std::make_unique<ExternalVkImageBacking>(
util::PassKey<ExternalVkImageBacking>(), mailbox, format, size,
- color_space, surface_origin, alpha_type, usage, context_state,
+ color_space, surface_origin, alpha_type, usage, std::move(context_state),
std::move(image), command_pool, use_separate_gl_texture);
if (!pixel_data.empty()) {
@@ -263,7 +265,7 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::Create(
// static
std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::CreateFromGMB(
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
VulkanCommandPool* command_pool,
const Mailbox& mailbox,
gfx::GpuMemoryBufferHandle handle,
@@ -293,11 +295,12 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::CreateFromGMB(
}
bool use_separate_gl_texture =
- UseSeparateGLTexture(context_state, resource_format);
+ UseSeparateGLTexture(context_state.get(), resource_format);
auto backing = std::make_unique<ExternalVkImageBacking>(
util::PassKey<ExternalVkImageBacking>(), mailbox, resource_format, size,
- color_space, surface_origin, alpha_type, usage, context_state,
- std::move(image), command_pool, use_separate_gl_texture);
+ color_space, surface_origin, alpha_type, usage,
+ std::move(context_state), std::move(image), command_pool,
+ use_separate_gl_texture);
backing->SetCleared();
return backing;
}
@@ -313,10 +316,10 @@ std::unique_ptr<ExternalVkImageBacking> ExternalVkImageBacking::CreateFromGMB(
if (!shared_memory_wrapper.Initialize(handle, size, resource_format))
return nullptr;
- auto backing =
- Create(context_state, command_pool, mailbox, resource_format, size,
- color_space, surface_origin, alpha_type, usage, image_usage_cache,
- base::span<const uint8_t>(), true /* using_gmb */);
+ auto backing = Create(std::move(context_state), command_pool, mailbox,
+ resource_format, size, color_space, surface_origin,
+ alpha_type, usage, image_usage_cache,
+ base::span<const uint8_t>(), true /* using_gmb */);
if (!backing)
return nullptr;
@@ -333,7 +336,7 @@ ExternalVkImageBacking::ExternalVkImageBacking(
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
std::unique_ptr<VulkanImage> image,
VulkanCommandPool* command_pool,
bool use_separate_gl_texture)
@@ -346,7 +349,7 @@ ExternalVkImageBacking::ExternalVkImageBacking(
usage,
image->device_size(),
false /* is_thread_safe */),
- context_state_(context_state),
+ context_state_(std::move(context_state)),
image_(std::move(image)),
backend_texture_(size.width(),
size.height(),
@@ -554,10 +557,8 @@ void ExternalVkImageBacking::AddSemaphoresToPendingListOrRelease(
// signalling but have not been signalled. In that case, we have to release
// them via fence helper to make sure all submitted GPU works is finished
// before releasing them.
- // |context_state_| is out live fence_helper, so it is safe to use
- // base::Unretained(context_state_).
fence_helper()->EnqueueCleanupTaskForSubmittedWork(base::BindOnce(
- [](SharedContextState* shared_context_state,
+ [](scoped_refptr<SharedContextState> shared_context_state,
std::vector<ExternalSemaphore>, VulkanDeviceQueue* device_queue,
bool device_lost) {
if (!gl::GLContext::GetCurrent()) {
@@ -565,7 +566,7 @@ void ExternalVkImageBacking::AddSemaphoresToPendingListOrRelease(
/*needs_gl=*/true);
}
},
- base::Unretained(context_state_), std::move(semaphores)));
+ context_state_, std::move(semaphores)));
}
}
@@ -582,7 +583,7 @@ std::unique_ptr<SharedImageRepresentationDawn>
ExternalVkImageBacking::ProduceDawn(SharedImageManager* manager,
MemoryTypeTracker* tracker,
WGPUDevice wgpuDevice) {
-#if defined(OS_LINUX) && BUILDFLAG(USE_DAWN)
+#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && BUILDFLAG(USE_DAWN)
auto wgpu_format = viz::ToWGPUFormat(format());
if (wgpu_format == WGPUTextureFormat_Undefined) {
@@ -601,7 +602,7 @@ ExternalVkImageBacking::ProduceDawn(SharedImageManager* manager,
return std::make_unique<ExternalVkImageDawnRepresentation>(
manager, this, tracker, wgpuDevice, wgpu_format, std::move(memory_fd));
-#else // !defined(OS_LINUX) || !BUILDFLAG(USE_DAWN)
+#else // (!defined(OS_LINUX) && !defined(OS_CHROMEOS)) || !BUILDFLAG(USE_DAWN)
NOTIMPLEMENTED_LOG_ONCE();
return nullptr;
#endif
@@ -614,7 +615,7 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() {
gl::GLApi* api = gl::g_current_gl_context;
base::Optional<ScopedDedicatedMemoryObject> memory_object;
if (!use_separate_gl_texture()) {
-#if defined(OS_LINUX) || defined(OS_ANDROID)
+#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID)
auto memory_fd = image_->GetMemoryFd();
if (!memory_fd.is_valid())
return 0;
@@ -662,7 +663,7 @@ GLuint ExternalVkImageBacking::ProduceGLTextureInternal() {
// If ANGLE_memory_object_flags is supported, use that to communicate the
// exact create and usage flags the image was created with.
DCHECK(image_->usage() != 0);
- if (UseMinimalUsageFlags(context_state_)) {
+ if (UseMinimalUsageFlags(context_state())) {
api->glTexStorageMemFlags2DANGLEFn(
GL_TEXTURE_2D, 1, internal_format, size().width(), size().height(),
memory_object->id(), 0, image_->flags(), image_->usage());
@@ -749,7 +750,7 @@ ExternalVkImageBacking::ProduceSkia(
scoped_refptr<SharedContextState> context_state) {
// This backing type is only used when vulkan is enabled, so SkiaRenderer
// should also be using Vulkan.
- DCHECK_EQ(context_state_, context_state.get());
+ DCHECK_EQ(context_state_, context_state);
DCHECK(context_state->GrContextIsVulkan());
return std::make_unique<ExternalVkImageSkiaRepresentation>(manager, this,
tracker);
diff --git a/chromium/gpu/command_buffer/service/external_vk_image_backing.h b/chromium/gpu/command_buffer/service/external_vk_image_backing.h
index 4d4523a4bd6..27397700c98 100644
--- a/chromium/gpu/command_buffer/service/external_vk_image_backing.h
+++ b/chromium/gpu/command_buffer/service/external_vk_image_backing.h
@@ -34,7 +34,7 @@ struct VulkanImageUsageCache {
class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
public:
static std::unique_ptr<ExternalVkImageBacking> Create(
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
VulkanCommandPool* command_pool,
const Mailbox& mailbox,
viz::ResourceFormat format,
@@ -48,7 +48,7 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
bool using_gmb = false);
static std::unique_ptr<ExternalVkImageBacking> CreateFromGMB(
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
VulkanCommandPool* command_pool,
const Mailbox& mailbox,
gfx::GpuMemoryBufferHandle handle,
@@ -68,14 +68,14 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
- SharedContextState* context_state,
+ scoped_refptr<SharedContextState> context_state,
std::unique_ptr<VulkanImage> image,
VulkanCommandPool* command_pool,
bool use_separate_gl_texture);
~ExternalVkImageBacking() override;
- SharedContextState* context_state() const { return context_state_; }
+ SharedContextState* context_state() const { return context_state_.get(); }
const GrBackendTexture& backend_texture() const { return backend_texture_; }
VulkanImage* image() const { return image_.get(); }
const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough()
@@ -178,7 +178,7 @@ class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking {
void CopyPixelsFromGLTextureToVkImage();
void CopyPixelsFromShmToGLTexture();
- SharedContextState* const context_state_;
+ scoped_refptr<SharedContextState> context_state_;
std::unique_ptr<VulkanImage> image_;
GrBackendTexture backend_texture_;
VulkanCommandPool* const command_pool_;
diff --git a/chromium/gpu/command_buffer/service/external_vk_image_factory.cc b/chromium/gpu/command_buffer/service/external_vk_image_factory.cc
index be1f1ad8cb1..1ac61030927 100644
--- a/chromium/gpu/command_buffer/service/external_vk_image_factory.cc
+++ b/chromium/gpu/command_buffer/service/external_vk_image_factory.cc
@@ -61,8 +61,8 @@ VulkanImageUsageCache CreateImageUsageCache(
} // namespace
ExternalVkImageFactory::ExternalVkImageFactory(
- SharedContextState* context_state)
- : context_state_(context_state),
+ scoped_refptr<SharedContextState> context_state)
+ : context_state_(std::move(context_state)),
command_pool_(context_state_->vk_context_provider()
->GetDeviceQueue()
->CreateCommandPool()),
diff --git a/chromium/gpu/command_buffer/service/external_vk_image_factory.h b/chromium/gpu/command_buffer/service/external_vk_image_factory.h
index 63d36f2a1ae..f736400c53b 100644
--- a/chromium/gpu/command_buffer/service/external_vk_image_factory.h
+++ b/chromium/gpu/command_buffer/service/external_vk_image_factory.h
@@ -22,7 +22,8 @@ class VulkanCommandPool;
// that allow it to be exported out and shared with GL.
class ExternalVkImageFactory : public SharedImageBackingFactory {
public:
- explicit ExternalVkImageFactory(SharedContextState* context_state);
+ explicit ExternalVkImageFactory(
+ scoped_refptr<SharedContextState> context_state);
~ExternalVkImageFactory() override;
// SharedImageBackingFactory implementation.
@@ -66,7 +67,7 @@ class ExternalVkImageFactory : public SharedImageBackingFactory {
void TransitionToColorAttachment(VkImage image);
- SharedContextState* const context_state_;
+ scoped_refptr<SharedContextState> context_state_;
std::unique_ptr<VulkanCommandPool> command_pool_;
const VulkanImageUsageCache image_usage_cache_;
diff --git a/chromium/gpu/command_buffer/service/external_vk_image_skia_representation.cc b/chromium/gpu/command_buffer/service/external_vk_image_skia_representation.cc
index 5a88fd66991..380d617ba45 100644
--- a/chromium/gpu/command_buffer/service/external_vk_image_skia_representation.cc
+++ b/chromium/gpu/command_buffer/service/external_vk_image_skia_representation.cc
@@ -85,7 +85,7 @@ sk_sp<SkSurface> ExternalVkImageSkiaRepresentation::BeginWriteAccess(
// VkImage to VK_QUEUE_FAMILY_EXTERNAL before calling EndAccess().
if (backing_impl()->need_synchronization()) {
*end_state = std::make_unique<GrBackendSurfaceMutableState>(
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_EXTERNAL);
+ VK_IMAGE_LAYOUT_UNDEFINED, VK_QUEUE_FAMILY_EXTERNAL);
}
return surface;
@@ -125,7 +125,7 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginReadAccess(
// VK_QUEUE_FAMILY_EXTERNAL before calling EndAccess().
if (!backing_impl()->use_separate_gl_texture()) {
*end_state = std::make_unique<GrBackendSurfaceMutableState>(
- VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_EXTERNAL);
+ VK_IMAGE_LAYOUT_UNDEFINED, VK_QUEUE_FAMILY_EXTERNAL);
}
access_mode_ = kRead;
diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc
index 422e1bd7d63..d51c538b1fa 100644
--- a/chromium/gpu/command_buffer/service/feature_info.cc
+++ b/chromium/gpu/command_buffer/service/feature_info.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/command_line.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
@@ -1822,96 +1823,131 @@ void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
if (may_enable_chromium_color_buffer_float &&
!had_native_chromium_color_buffer_float_ext) {
- static_assert(GL_RGBA32F_ARB == GL_RGBA32F &&
- GL_RGBA32F_EXT == GL_RGBA32F &&
- GL_RGB32F_ARB == GL_RGB32F && GL_RGB32F_EXT == GL_RGB32F,
- "sized float internal format variations must match");
- // We don't check extension support beyond ARB_texture_float on desktop GL,
- // and format support varies between GL configurations. For example, spec
- // prior to OpenGL 3.0 mandates framebuffer support only for one
- // implementation-chosen format, and ES3.0 EXT_color_buffer_float does not
- // support rendering to RGB32F. Check for framebuffer completeness with
- // formats that the extensions expose, and only enable an extension when a
- // framebuffer created with its texture format is reported as complete.
- GLint fb_binding = 0;
- GLint tex_binding = 0;
- glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding);
- glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding);
-
- GLuint tex_id = 0;
- GLuint fb_id = 0;
- GLsizei width = 16;
-
- glGenTextures(1, &tex_id);
- glGenFramebuffersEXT(1, &fb_id);
- glBindTexture(GL_TEXTURE_2D, tex_id);
- // Nearest filter needed for framebuffer completeness on some drivers.
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0, GL_RGBA,
- GL_FLOAT, nullptr);
- glBindFramebufferEXT(GL_FRAMEBUFFER, fb_id);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, tex_id, 0);
- GLenum status_rgba = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0, GL_RGB, GL_FLOAT,
- nullptr);
- GLenum status_rgb = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
-
- // For desktop systems, check to see if we support rendering to the full
- // range of formats supported by EXT_color_buffer_float
- if (status_rgba == GL_FRAMEBUFFER_COMPLETE && enable_es3) {
- bool full_float_support = true;
- GLenum internal_formats[] = {
- GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_R11F_G11F_B10F,
- };
- GLenum formats[] = {
- GL_RED, GL_RG, GL_RGBA, GL_RED, GL_RG, GL_RGB,
- };
- DCHECK_EQ(base::size(internal_formats), base::size(formats));
- for (size_t i = 0; i < base::size(formats); ++i) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], width, width, 0,
- formats[i], GL_FLOAT, nullptr);
- full_float_support &= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
- GL_FRAMEBUFFER_COMPLETE;
+ if (workarounds_.force_enable_color_buffer_float ||
+ workarounds_.force_enable_color_buffer_float_except_rgb32f) {
+ if (enable_es3)
+ enable_ext_color_buffer_float = true;
+ if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float &&
+ gl_version_info_->IsAtLeastGL(3, 0)) {
+ enable_ext_color_buffer_half_float = true;
+ }
+ feature_flags_.chromium_color_buffer_float_rgba = true;
+ if (!disallowed_features_.chromium_color_buffer_float_rgba)
+ EnableCHROMIUMColorBufferFloatRGBA();
+ if (!workarounds_.force_enable_color_buffer_float_except_rgb32f) {
+ feature_flags_.chromium_color_buffer_float_rgb = true;
+ if (!disallowed_features_.chromium_color_buffer_float_rgb)
+ EnableCHROMIUMColorBufferFloatRGB();
+ }
+ } else {
+ static_assert(
+ GL_RGBA32F_ARB == GL_RGBA32F && GL_RGBA32F_EXT == GL_RGBA32F &&
+ GL_RGB32F_ARB == GL_RGB32F && GL_RGB32F_EXT == GL_RGB32F,
+ "sized float internal format variations must match");
+ // We don't check extension support beyond ARB_texture_float on desktop
+ // GL, and format support varies between GL configurations. For example,
+ // spec prior to OpenGL 3.0 mandates framebuffer support only for one
+ // implementation-chosen format, and ES3.0 EXT_color_buffer_float does not
+ // support rendering to RGB32F. Check for framebuffer completeness with
+ // formats that the extensions expose, and only enable an extension when a
+ // framebuffer created with its texture format is reported as complete.
+ GLint fb_binding = 0;
+ GLint tex_binding = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb_binding);
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex_binding);
+
+ GLuint tex_id = 0;
+ GLuint fb_id = 0;
+ GLsizei width = 16;
+
+ glGenTextures(1, &tex_id);
+ glGenFramebuffersEXT(1, &fb_id);
+ glBindTexture(GL_TEXTURE_2D, tex_id);
+ // Nearest filter needed for framebuffer completeness on some drivers.
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, width, 0, GL_RGBA,
+ GL_FLOAT, nullptr);
+ glBindFramebufferEXT(GL_FRAMEBUFFER, fb_id);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, tex_id, 0);
+ GLenum status_rgba = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, width, 0, GL_RGB,
+ GL_FLOAT, nullptr);
+ GLenum status_rgb = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
+ base::UmaHistogramBoolean("GPU.RenderableFormat.RGBA32F.FLOAT",
+ status_rgba == GL_FRAMEBUFFER_COMPLETE);
+ base::UmaHistogramBoolean("GPU.RenderableFormat.RGB32F.FLOAT",
+ status_rgb == GL_FRAMEBUFFER_COMPLETE);
+
+ // For desktop systems, check to see if we support rendering to the full
+ // range of formats supported by EXT_color_buffer_float
+ if (status_rgba == GL_FRAMEBUFFER_COMPLETE && enable_es3) {
+ bool full_float_support = true;
+ const GLenum kInternalFormats[] = {
+ GL_R16F, GL_RG16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_R11F_G11F_B10F,
+ };
+ const GLenum kFormats[] = {
+ GL_RED, GL_RG, GL_RGBA, GL_RED, GL_RG, GL_RGB,
+ };
+ const char* kInternalFormatHistogramNames[] = {
+ "GPU.RenderableFormat.R16F.FLOAT",
+ "GPU.RenderableFormat.RG16F.FLOAT",
+ "GPU.RenderableFormat.RGBA16F.FLOAT",
+ "GPU.RenderableFormat.R32F.FLOAT",
+ "GPU.RenderableFormat.RG32F.FLOAT",
+ "GPU.RenderableFormat.R11F_G11F_B10F.FLOAT",
+ };
+ DCHECK_EQ(base::size(kInternalFormats), base::size(kFormats));
+ for (size_t i = 0; i < base::size(kFormats); ++i) {
+ glTexImage2D(GL_TEXTURE_2D, 0, kInternalFormats[i], width, width, 0,
+ kFormats[i], GL_FLOAT, nullptr);
+ bool supported = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
+ GL_FRAMEBUFFER_COMPLETE;
+ base::UmaHistogramBoolean(kInternalFormatHistogramNames[i],
+ supported);
+ full_float_support &= supported;
+ }
+ enable_ext_color_buffer_float = full_float_support;
+ }
+ // Likewise for EXT_color_buffer_half_float on ES2 contexts. On desktop,
+ // require at least GL 3.0, to ensure that all formats are defined.
+ if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float &&
+ (gl_version_info_->IsAtLeastGLES(3, 0) ||
+ gl_version_info_->IsAtLeastGL(3, 0))) {
+ // EXT_color_buffer_half_float requires at least one of the formats is
+ // supported to be color-renderable. WebGL's extension requires RGBA16F
+ // to be the supported effective format. Here we only expose the
+ // extension if RGBA16F is color-renderable.
+ GLenum internal_format = GL_RGBA16F;
+ GLenum format = GL_RGBA;
+ GLenum data_type = GL_HALF_FLOAT;
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, width, 0, format,
+ data_type, nullptr);
+ bool supported = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
+ GL_FRAMEBUFFER_COMPLETE;
+ base::UmaHistogramBoolean("GPU.RenderableFormat.RGBA16F.HALF_FLOAT",
+ supported);
+ enable_ext_color_buffer_half_float = supported;
}
- enable_ext_color_buffer_float = full_float_support;
- }
- // Likewise for EXT_color_buffer_half_float on ES2 contexts. On desktop,
- // require at least GL 3.0, to ensure that all formats are defined.
- if (IsWebGL1OrES2Context() && !enable_ext_color_buffer_half_float &&
- (gl_version_info_->IsAtLeastGLES(3, 0) ||
- gl_version_info_->IsAtLeastGL(3, 0))) {
- // EXT_color_buffer_half_float requires at least one of the formats is
- // supported to be color-renderable. WebGL's extension requires RGBA16F
- // to be the supported effective format. Here we only expose the extension
- // if RGBA16F is color-renderable.
- GLenum internal_format = GL_RGBA16F;
- GLenum format = GL_RGBA;
- GLenum data_type = GL_HALF_FLOAT;
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, width, 0, format,
- data_type, nullptr);
- enable_ext_color_buffer_half_float =
- (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) ==
- GL_FRAMEBUFFER_COMPLETE);
- }
- glDeleteFramebuffersEXT(1, &fb_id);
- glDeleteTextures(1, &tex_id);
+ glDeleteFramebuffersEXT(1, &fb_id);
+ glDeleteTextures(1, &tex_id);
- glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding));
- glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding));
+ glBindFramebufferEXT(GL_FRAMEBUFFER, static_cast<GLuint>(fb_binding));
+ glBindTexture(GL_TEXTURE_2D, static_cast<GLuint>(tex_binding));
- DCHECK_EQ(glGetError(), static_cast<GLuint>(GL_NO_ERROR));
+ DCHECK_EQ(glGetError(), static_cast<GLuint>(GL_NO_ERROR));
- if (status_rgba == GL_FRAMEBUFFER_COMPLETE) {
- feature_flags_.chromium_color_buffer_float_rgba = true;
- if (!disallowed_features_.chromium_color_buffer_float_rgba)
- EnableCHROMIUMColorBufferFloatRGBA();
- }
- if (status_rgb == GL_FRAMEBUFFER_COMPLETE) {
- feature_flags_.chromium_color_buffer_float_rgb = true;
- if (!disallowed_features_.chromium_color_buffer_float_rgb)
- EnableCHROMIUMColorBufferFloatRGB();
+ if (status_rgba == GL_FRAMEBUFFER_COMPLETE) {
+ feature_flags_.chromium_color_buffer_float_rgba = true;
+ if (!disallowed_features_.chromium_color_buffer_float_rgba)
+ EnableCHROMIUMColorBufferFloatRGBA();
+ }
+ if (status_rgb == GL_FRAMEBUFFER_COMPLETE) {
+ feature_flags_.chromium_color_buffer_float_rgb = true;
+ if (!disallowed_features_.chromium_color_buffer_float_rgb)
+ EnableCHROMIUMColorBufferFloatRGB();
+ }
}
}
diff --git a/chromium/gpu/command_buffer/service/gl_utils.cc b/chromium/gpu/command_buffer/service/gl_utils.cc
index 0755855b068..6099654615f 100644
--- a/chromium/gpu/command_buffer/service/gl_utils.cc
+++ b/chromium/gpu/command_buffer/service/gl_utils.cc
@@ -47,11 +47,9 @@ bool IsValidPVRTCSize(GLint level, GLsizei size) {
}
bool IsValidS3TCSizeForWebGLAndANGLE(GLint level, GLsizei size) {
- // WebGL and ANGLE only allow multiple-of-4 sizes, except for levels > 0 where
- // it also allows 1 or 2. See WEBGL_compressed_texture_s3tc and
- // ANGLE_compressed_texture_dxt*
- return (level && size == 1) || (level && size == 2) ||
- !(size % kS3TCBlockWidth);
+ // WebGL and ANGLE only allow multiple-of-4 sizes for the base level. See
+ // WEBGL_compressed_texture_s3tc and ANGLE_compressed_texture_dxt*
+ return (level > 0) || (size % kS3TCBlockWidth == 0);
}
const char* GetDebugSourceString(GLenum source) {
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 2c87eac1bea..2d5ca431c5c 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -13981,16 +13981,15 @@ void GLES2DecoderImpl::DoScheduleCALayerInUseQueryCHROMIUM(
gl::GLImage* image = nullptr;
GLuint texture_id = textures[i];
if (texture_id) {
+ // If a |texture_id| is invalid (due to a client error), report that it
+ // is not in use. Failing the GL call can result in compositor hangs.
+ // https://crbug.com/1120795
TextureRef* ref = texture_manager()->GetTexture(texture_id);
- if (!ref) {
- LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
- "glScheduleCALayerInUseQueryCHROMIUM",
- "unknown texture");
- return;
+ if (ref) {
+ Texture::ImageState image_state;
+ image = ref->texture()->GetLevelImage(ref->texture()->target(), 0,
+ &image_state);
}
- Texture::ImageState image_state;
- image = ref->texture()->GetLevelImage(ref->texture()->target(), 0,
- &image_state);
}
gl::GLSurface::CALayerInUseQuery query;
query.image = image;
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 7a44b17b907..045c71984cb 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -265,6 +265,27 @@ void UpdateBoundTexturePassthroughSize(gl::GLApi* api,
texture->SetEstimatedSize(texture_memory_size);
}
+void ReturnProgramInfoData(DecoderClient* client,
+ const std::vector<uint8_t>& info,
+ GLES2ReturnDataType type,
+ uint32_t program) {
+ // Limit the data size in order not to block the IO threads too long.
+ // https://docs.google.com/document/d/1qEfU0lAkeZ8lU06qtxv7ENGxRxExxztXu1LhIDNGqtU/edit?disco=AAAACksORlU
+ constexpr static size_t kMaxDataSize = 8 * 1024 * 1024;
+ if (info.size() > kMaxDataSize)
+ return;
+
+ std::vector<uint8_t> return_data;
+ return_data.resize(sizeof(cmds::GLES2ReturnProgramInfo) + info.size());
+ auto* return_program_info =
+ reinterpret_cast<cmds::GLES2ReturnProgramInfo*>(return_data.data());
+ return_program_info->return_data_header.return_data_type = type;
+ return_program_info->program_client_id = program;
+ memcpy(return_program_info->deserialized_buffer, info.data(), info.size());
+ client->HandleReturnData(
+ base::span<uint8_t>(return_data.data(), return_data.size()));
+}
+
} // anonymous namespace
GLES2DecoderPassthroughImpl::TexturePendingBinding::TexturePendingBinding(
@@ -2469,6 +2490,52 @@ error::Error GLES2DecoderPassthroughImpl::ProcessQueries(bool did_finish) {
api()->glGetProgramivFn(query.program_service_id, GL_LINK_STATUS,
&link_status);
result = link_status;
+
+ // Send back all program information as early as possible to be cached
+ // at the client side.
+ GLuint program_client_id = 0u;
+ GetClientID(&resources_->program_id_map, query.program_service_id,
+ &program_client_id);
+
+ // TODO(jie.a.chen@intel.com): Merge the all return data into 1 IPC
+ // message if it becomes a concern.
+ std::vector<uint8_t> program_info;
+ error::Error error =
+ DoGetProgramInfoCHROMIUM(program_client_id, &program_info);
+ if (error == error::kNoError) {
+ ReturnProgramInfoData(client(), program_info,
+ GLES2ReturnDataType::kES2ProgramInfo,
+ program_client_id);
+ }
+
+ if (feature_info_->IsWebGL2OrES3OrHigherContext()) {
+ std::vector<uint8_t> uniform_blocks;
+ error =
+ DoGetUniformBlocksCHROMIUM(program_client_id, &uniform_blocks);
+ if (error == error::kNoError) {
+ ReturnProgramInfoData(client(), uniform_blocks,
+ GLES2ReturnDataType::kES3UniformBlocks,
+ program_client_id);
+ }
+
+ std::vector<uint8_t> transform_feedback_varyings;
+ error = DoGetTransformFeedbackVaryingsCHROMIUM(
+ program_client_id, &transform_feedback_varyings);
+ if (error == error::kNoError) {
+ ReturnProgramInfoData(
+ client(), transform_feedback_varyings,
+ GLES2ReturnDataType::kES3TransformFeedbackVaryings,
+ program_client_id);
+ }
+
+ std::vector<uint8_t> uniforms;
+ error = DoGetUniformsES3CHROMIUM(program_client_id, &uniforms);
+ if (error == error::kNoError) {
+ ReturnProgramInfoData(client(), uniforms,
+ GLES2ReturnDataType::kES3Uniforms,
+ program_client_id);
+ }
+ }
}
break;
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 6c9948d52a4..f6edc0fbce7 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1289,8 +1289,14 @@ error::Error GLES2DecoderPassthroughImpl::DoFenceSync(GLenum condition,
}
error::Error GLES2DecoderPassthroughImpl::DoFinish() {
+ // Finish can take a long time, make sure the watchdog gives it the most
+ // amount of time to complete.
+ group_->ReportProgress();
+
api()->glFinishFn();
+ group_->ReportProgress();
+
error::Error error = ProcessReadPixels(true);
if (error != error::kNoError) {
return error;
@@ -1518,9 +1524,11 @@ error::Error GLES2DecoderPassthroughImpl::DoGetActiveAttrib(GLuint program,
}
std::vector<char> name_buffer(active_attribute_max_length, 0);
- api()->glGetActiveAttribFn(service_id, index, name_buffer.size(), nullptr,
+ GLsizei length = 0;
+ api()->glGetActiveAttribFn(service_id, index, name_buffer.size(), &length,
size, type, name_buffer.data());
- *name = std::string(name_buffer.data());
+ DCHECK(length <= active_attribute_max_length);
+ *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
*success = CheckErrorCallbackState() ? 0 : 1;
return error::kNoError;
}
@@ -1543,9 +1551,11 @@ error::Error GLES2DecoderPassthroughImpl::DoGetActiveUniform(GLuint program,
}
std::vector<char> name_buffer(active_uniform_max_length, 0);
- api()->glGetActiveUniformFn(service_id, index, name_buffer.size(), nullptr,
+ GLsizei length = 0;
+ api()->glGetActiveUniformFn(service_id, index, name_buffer.size(), &length,
size, type, name_buffer.data());
- *name = std::string(name_buffer.data());
+ DCHECK(length <= active_uniform_max_length);
+ *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
*success = CheckErrorCallbackState() ? 0 : 1;
return error::kNoError;
}
@@ -2080,10 +2090,12 @@ error::Error GLES2DecoderPassthroughImpl::DoGetTransformFeedbackVarying(
}
std::vector<char> name_buffer(transform_feedback_varying_max_length, 0);
+ GLsizei length = 0;
api()->glGetTransformFeedbackVaryingFn(service_id, index, name_buffer.size(),
- nullptr, size, type,
+ &length, size, type,
name_buffer.data());
- *name = std::string(name_buffer.data());
+ DCHECK(length <= transform_feedback_varying_max_length);
+ *name = length > 0 ? std::string(name_buffer.data(), length) : std::string();
*success = CheckErrorCallbackState() ? 0 : 1;
return error::kNoError;
}
@@ -4388,9 +4400,13 @@ error::Error GLES2DecoderPassthroughImpl::DoGetTranslatedShaderSourceANGLE(
if (translated_source_length > 0) {
std::vector<char> buffer(translated_source_length, 0);
+ GLsizei length = 0;
api()->glGetTranslatedShaderSourceANGLEFn(
- service_id, translated_source_length, nullptr, buffer.data());
- *source = std::string(buffer.data());
+ service_id, translated_source_length, &length, buffer.data());
+ DCHECK(length <= translated_source_length);
+ *source = length > 0 ? std::string(buffer.data(), length) : std::string();
+ } else {
+ *source = std::string();
}
return error::kNoError;
}
@@ -4909,15 +4925,17 @@ error::Error GLES2DecoderPassthroughImpl::DoScheduleCALayerInUseQueryCHROMIUM(
gl::GLImage* image = nullptr;
GLuint texture_id = textures[i];
if (texture_id) {
+ // If a |texture_id| is invalid (due to a client error), report that it
+ // is not in use. Failing the GL call can result in compositor hangs.
+ // https://crbug.com/1120795
scoped_refptr<TexturePassthrough> passthrough_texture;
- if (!resources_->texture_object_map.GetServiceID(texture_id,
- &passthrough_texture) ||
- passthrough_texture == nullptr) {
- InsertError(GL_INVALID_VALUE, "unknown texture");
- return error::kNoError;
+ if (resources_->texture_object_map.GetServiceID(texture_id,
+ &passthrough_texture)) {
+ if (passthrough_texture) {
+ image = passthrough_texture->GetLevelImage(
+ passthrough_texture->target(), 0);
+ }
}
- image =
- passthrough_texture->GetLevelImage(passthrough_texture->target(), 0);
}
gl::GLSurface::CALayerInUseQuery query;
query.image = image;
diff --git a/chromium/gpu/command_buffer/service/gpu_fence_manager.cc b/chromium/gpu/command_buffer/service/gpu_fence_manager.cc
index c7e11638b0c..b70675a1c6a 100644
--- a/chromium/gpu/command_buffer/service/gpu_fence_manager.cc
+++ b/chromium/gpu/command_buffer/service/gpu_fence_manager.cc
@@ -40,9 +40,8 @@ bool GpuFenceManager::CreateGpuFence(uint32_t client_id) {
return true;
}
-bool GpuFenceManager::CreateGpuFenceFromHandle(
- uint32_t client_id,
- const gfx::GpuFenceHandle& handle) {
+bool GpuFenceManager::CreateGpuFenceFromHandle(uint32_t client_id,
+ gfx::GpuFenceHandle handle) {
// The handle must be valid. The fallback kEmpty type cannot be duplicated.
if (handle.is_null())
return false;
@@ -52,7 +51,7 @@ bool GpuFenceManager::CreateGpuFenceFromHandle(
if (it != gpu_fence_entries_.end())
return false;
- gfx::GpuFence gpu_fence(handle);
+ gfx::GpuFence gpu_fence(std::move(handle));
auto entry = std::make_unique<GpuFenceEntry>();
entry->gl_fence_ = gl::GLFence::CreateFromGpuFence(gpu_fence);
if (!entry->gl_fence_)
diff --git a/chromium/gpu/command_buffer/service/gpu_fence_manager.h b/chromium/gpu/command_buffer/service/gpu_fence_manager.h
index c6e03a800eb..ee50d6fddd1 100644
--- a/chromium/gpu/command_buffer/service/gpu_fence_manager.h
+++ b/chromium/gpu/command_buffer/service/gpu_fence_manager.h
@@ -48,8 +48,7 @@ class GPU_GLES2_EXPORT GpuFenceManager {
bool CreateGpuFence(uint32_t client_id);
- bool CreateGpuFenceFromHandle(uint32_t client_id,
- const gfx::GpuFenceHandle& handle);
+ bool CreateGpuFenceFromHandle(uint32_t client_id, gfx::GpuFenceHandle handle);
bool IsValidGpuFence(uint32_t client_id);
diff --git a/chromium/gpu/command_buffer/service/gpu_fence_manager_unittest.cc b/chromium/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
index cc96195a153..20e5dee63c8 100644
--- a/chromium/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
+++ b/chromium/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
@@ -172,10 +172,9 @@ TEST_F(GpuFenceManagerTest, GetGpuFence) {
.RetiresOnSaturation();
std::unique_ptr<gfx::GpuFence> gpu_fence = manager_->GetGpuFence(kClient1Id);
EXPECT_TRUE(gpu_fence);
- gfx::GpuFenceHandle handle = gpu_fence->GetGpuFenceHandle();
+ const gfx::GpuFenceHandle& handle = gpu_fence->GetGpuFenceHandle();
- EXPECT_EQ(handle.type, gfx::GpuFenceHandleType::kAndroidNativeFenceSync);
- EXPECT_EQ(handle.native_fd.fd, kFenceFD);
+ EXPECT_EQ(handle.owned_fd.get(), kFenceFD);
// Removing the fence marks it invalid.
EXPECT_CALL(*egl_, DestroySyncKHR(_, kDummySync))
@@ -194,8 +193,7 @@ TEST_F(GpuFenceManagerTest, Duplication) {
// Create a handle.
gfx::GpuFenceHandle handle;
- handle.type = gfx::GpuFenceHandleType::kAndroidNativeFenceSync;
- handle.native_fd = base::FileDescriptor(kFenceFD, true);
+ handle.owned_fd = base::ScopedFD(kFenceFD);
// Create a duplicate fence object from it.
EXPECT_CALL(*egl_, CreateSyncKHR(_, EGL_SYNC_NATIVE_FENCE_ANDROID, _))
@@ -203,7 +201,8 @@ TEST_F(GpuFenceManagerTest, Duplication) {
.WillOnce(Return(kDummySync))
.RetiresOnSaturation();
EXPECT_CALL(*gl_, Flush()).Times(1).RetiresOnSaturation();
- EXPECT_TRUE(manager_->CreateGpuFenceFromHandle(kClient1Id, handle));
+ EXPECT_TRUE(
+ manager_->CreateGpuFenceFromHandle(kClient1Id, std::move(handle)));
EXPECT_TRUE(manager_->IsValidGpuFence(kClient1Id));
// Try a server wait on it.
diff --git a/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc b/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc
index bfc7f47b66a..837750ffa17 100644
--- a/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc
+++ b/chromium/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -9,6 +9,7 @@
#include <stdint.h>
#include "base/android/android_hardware_buffer_compat.h"
+#include "base/android/android_image_reader_compat.h"
#include "base/android/jni_android.h"
#include "base/android/scoped_hardware_buffer_fence_sync.h"
#include "base/logging.h"
@@ -20,7 +21,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "gpu/command_buffer/service/abstract_texture.h"
#include "gpu/ipc/common/android/android_image_reader_utils.h"
-#include "media/base/android/media_codec_util.h"
#include "ui/gl/android/android_surface_control_compat.h"
#include "ui/gl/gl_fence_android_native_fence_sync.h"
#include "ui/gl/gl_utils.h"
@@ -62,10 +62,11 @@ bool IsSurfaceControl(TextureOwner::Mode mode) {
uint32_t NumRequiredMaxImages(TextureOwner::Mode mode) {
if (IsSurfaceControl(mode) ||
mode == TextureOwner::Mode::kAImageReaderInsecureMultithreaded) {
- DCHECK(!media::MediaCodecUtil::LimitAImageReaderMaxSizeToOne());
+ DCHECK(!base::android::AndroidImageReader::LimitAImageReaderMaxSizeToOne());
return 3;
}
- return media::MediaCodecUtil::LimitAImageReaderMaxSizeToOne() ? 1 : 2;
+ return base::android::AndroidImageReader::LimitAImageReaderMaxSizeToOne() ? 1
+ : 2;
}
} // namespace
diff --git a/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc b/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc
index 2f03c9f174a..cd675ad2fe7 100644
--- a/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc
+++ b/chromium/gpu/command_buffer/service/image_reader_gl_owner_unittest.cc
@@ -8,11 +8,11 @@
#include <memory>
#include <utility>
+#include "base/android/android_image_reader_compat.h"
#include "base/test/task_environment.h"
#include "gpu/command_buffer/service/abstract_texture.h"
#include "gpu/command_buffer/service/image_reader_gl_owner.h"
#include "gpu/command_buffer/service/mock_abstract_texture.h"
-#include "media/base/android/media_codec_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context_egl.h"
@@ -149,7 +149,9 @@ TEST_F(ImageReaderGLOwnerTest, MaxImageExpectation) {
return;
EXPECT_EQ(static_cast<ImageReaderGLOwner*>(image_reader_.get())
->max_images_for_testing(),
- media::MediaCodecUtil::LimitAImageReaderMaxSizeToOne() ? 1 : 2);
+ base::android::AndroidImageReader::LimitAImageReaderMaxSizeToOne()
+ ? 1
+ : 2);
}
class ImageReaderGLOwnerSecureSurfaceControlTest
diff --git a/chromium/gpu/command_buffer/service/raster_decoder.cc b/chromium/gpu/command_buffer/service/raster_decoder.cc
index f6e682699d3..04e3061f74d 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder.cc
+++ b/chromium/gpu/command_buffer/service/raster_decoder.cc
@@ -65,6 +65,7 @@
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
#include "third_party/skia/include/core/SkTypeface.h"
+#include "third_party/skia/include/core/SkYUVAIndex.h"
#include "third_party/skia/include/gpu/GrBackendSemaphore.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
diff --git a/chromium/gpu/command_buffer/service/shared_context_state.cc b/chromium/gpu/command_buffer/service/shared_context_state.cc
index bc48671c5c2..eaf0b3a4a0c 100644
--- a/chromium/gpu/command_buffer/service/shared_context_state.cc
+++ b/chromium/gpu/command_buffer/service/shared_context_state.cc
@@ -734,45 +734,40 @@ QueryManager* SharedContextState::GetQueryManager() {
return nullptr;
}
-bool SharedContextState::CheckResetStatus(bool needs_gl) {
+base::Optional<error::ContextLostReason> SharedContextState::GetResetStatus(
+ bool needs_gl) {
DCHECK(!context_lost());
- if (device_needs_reset_)
- return true;
-
if (gr_context_) {
// Maybe Skia detected VK_ERROR_DEVICE_LOST.
if (gr_context_->abandoned()) {
LOG(ERROR) << "SharedContextState context lost via Skia.";
- device_needs_reset_ = true;
- MarkContextLost(error::kUnknown);
- return true;
+ return error::kUnknown;
}
if (gr_context_->oomed()) {
LOG(ERROR) << "SharedContextState context lost via Skia OOM.";
- device_needs_reset_ = true;
- MarkContextLost(error::kOutOfMemory);
- return true;
+ return error::kOutOfMemory;
}
}
// Not using GL.
if (!GrContextIsGL() && !needs_gl)
- return false;
+ return base::nullopt;
// GL is not initialized.
if (!context_state_)
- return false;
+ return base::nullopt;
- GLenum error = context_state_->api()->glGetErrorFn();
- if (error == GL_OUT_OF_MEMORY) {
- LOG(ERROR) << "SharedContextState lost due to GL_OUT_OF_MEMORY";
- MarkContextLost(error::kOutOfMemory);
- device_needs_reset_ = true;
- return true;
+ GLenum error;
+ while ((error = context_state_->api()->glGetErrorFn()) != GL_NO_ERROR) {
+ if (error == GL_OUT_OF_MEMORY) {
+ LOG(ERROR) << "SharedContextState lost due to GL_OUT_OF_MEMORY";
+ return error::kOutOfMemory;
+ }
+ if (error == GL_CONTEXT_LOST_KHR)
+ break;
}
-
// Checking the reset status is expensive on some OS/drivers
// (https://crbug.com/1090232). Rate limit it.
constexpr base::TimeDelta kMinCheckDelay =
@@ -780,33 +775,42 @@ bool SharedContextState::CheckResetStatus(bool needs_gl) {
base::Time now = base::Time::Now();
if (!disable_check_reset_status_throttling_for_test_ &&
now < last_gl_check_graphics_reset_status_ + kMinCheckDelay) {
- return false;
+ return base::nullopt;
}
last_gl_check_graphics_reset_status_ = now;
GLenum driver_status = context()->CheckStickyGraphicsResetStatus();
if (driver_status == GL_NO_ERROR)
- return false;
+ return base::nullopt;
LOG(ERROR) << "SharedContextState context lost via ARB/EXT_robustness. Reset "
"status = "
<< gles2::GLES2Util::GetStringEnum(driver_status);
- device_needs_reset_ = true;
switch (driver_status) {
case GL_GUILTY_CONTEXT_RESET_ARB:
- MarkContextLost(error::kGuilty);
- break;
+ return error::kGuilty;
case GL_INNOCENT_CONTEXT_RESET_ARB:
- MarkContextLost(error::kInnocent);
- break;
+ return error::kInnocent;
case GL_UNKNOWN_CONTEXT_RESET_ARB:
- MarkContextLost(error::kUnknown);
- break;
+ return error::kUnknown;
default:
NOTREACHED();
break;
}
- return true;
+ return base::nullopt;
+}
+
+bool SharedContextState::CheckResetStatus(bool need_gl) {
+ DCHECK(!context_lost());
+ DCHECK(!device_needs_reset_);
+
+ auto status = GetResetStatus(need_gl);
+ if (status.has_value()) {
+ device_needs_reset_ = true;
+ MarkContextLost(status.value());
+ return true;
+ }
+ return false;
}
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/shared_context_state.h b/chromium/gpu/command_buffer/service/shared_context_state.h
index 02416325bdf..bcba574d587 100644
--- a/chromium/gpu/command_buffer/service/shared_context_state.h
+++ b/chromium/gpu/command_buffer/service/shared_context_state.h
@@ -273,6 +273,8 @@ class GPU_GLES2_EXPORT SharedContextState
~SharedContextState() override;
+ base::Optional<error::ContextLostReason> GetResetStatus(bool needs_gl);
+
// gpu::GLContextVirtualDelegate implementation.
bool initialized() const override;
const gles2::ContextState* GetContextState() override;
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc
index 194259c931c..05748005ef1 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.cc
@@ -6,6 +6,7 @@
#include "base/trace_event/memory_dump_manager.h"
#include "components/viz/common/resources/resource_format_utils.h"
+#include "components/viz/common/resources/resource_sizes.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/service/shared_image_representation_d3d.h"
#include "gpu/command_buffer/service/shared_image_representation_skia_gl.h"
@@ -45,7 +46,7 @@ SharedImageBackingD3D::SharedImageBackingD3D(
uint32_t usage,
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain,
scoped_refptr<gles2::TexturePassthrough> texture,
- scoped_refptr<gl::GLImageD3D> image,
+ scoped_refptr<gl::GLImage> image,
size_t buffer_index,
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture,
base::win::ScopedHandle shared_handle,
@@ -66,7 +67,6 @@ SharedImageBackingD3D::SharedImageBackingD3D(
d3d11_texture_(std::move(d3d11_texture)),
shared_handle_(std::move(shared_handle)),
dxgi_keyed_mutex_(std::move(dxgi_keyed_mutex)) {
- DCHECK(d3d11_texture_);
DCHECK(texture_);
}
@@ -171,6 +171,10 @@ HANDLE SharedImageBackingD3D::GetSharedHandle() const {
return shared_handle_.Get();
}
+gl::GLImage* SharedImageBackingD3D::GetGLImage() const {
+ return image_.get();
+}
+
bool SharedImageBackingD3D::PresentSwapChain() {
TRACE_EVENT0("gpu", "SharedImageBackingD3D::PresentSwapChain");
if (buffer_index_ != 0) {
@@ -195,7 +199,7 @@ bool SharedImageBackingD3D::PresentSwapChain() {
api->glBindTextureFn(GL_TEXTURE_2D, texture_->service_id());
if (!image_->BindTexImage(GL_TEXTURE_2D)) {
- DLOG(ERROR) << "GLImageD3D::BindTexImage failed";
+ DLOG(ERROR) << "GLImage::BindTexImage failed";
return false;
}
@@ -223,4 +227,12 @@ SharedImageBackingD3D::ProduceSkia(
manager, this, tracker);
}
+std::unique_ptr<SharedImageRepresentationOverlay>
+SharedImageBackingD3D::ProduceOverlay(SharedImageManager* manager,
+ MemoryTypeTracker* tracker) {
+ TRACE_EVENT0("gpu", "SharedImageBackingD3D::ProduceOverlay");
+ return std::make_unique<SharedImageRepresentationOverlayD3D>(manager, this,
+ tracker);
+}
+
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h
index a808c3c14bd..50e0645458c 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_d3d.h
@@ -32,7 +32,8 @@ struct Mailbox;
// Implementation of SharedImageBacking that holds buffer (front buffer/back
// buffer of swap chain) texture (as gles2::Texture/gles2::TexturePassthrough)
// and a reference to created swap chain.
-class SharedImageBackingD3D : public ClearTrackingSharedImageBacking {
+class GPU_GLES2_EXPORT SharedImageBackingD3D
+ : public ClearTrackingSharedImageBacking {
public:
SharedImageBackingD3D(
const Mailbox& mailbox,
@@ -44,7 +45,7 @@ class SharedImageBackingD3D : public ClearTrackingSharedImageBacking {
uint32_t usage,
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain,
scoped_refptr<gles2::TexturePassthrough> texture,
- scoped_refptr<gl::GLImageD3D> image,
+ scoped_refptr<gl::GLImage> image,
size_t buffer_index,
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture,
base::win::ScopedHandle shared_handle,
@@ -73,6 +74,7 @@ class SharedImageBackingD3D : public ClearTrackingSharedImageBacking {
void EndAccessD3D11();
HANDLE GetSharedHandle() const;
+ gl::GLImage* GetGLImage() const;
bool PresentSwapChain() override;
@@ -81,6 +83,10 @@ class SharedImageBackingD3D : public ClearTrackingSharedImageBacking {
ProduceGLTexturePassthrough(SharedImageManager* manager,
MemoryTypeTracker* tracker) override;
+ std::unique_ptr<SharedImageRepresentationOverlay> ProduceOverlay(
+ SharedImageManager* manager,
+ MemoryTypeTracker* tracker) override;
+
std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
@@ -89,8 +95,10 @@ class SharedImageBackingD3D : public ClearTrackingSharedImageBacking {
private:
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_;
scoped_refptr<gles2::TexturePassthrough> texture_;
- scoped_refptr<gl::GLImageD3D> image_;
+ scoped_refptr<gl::GLImage> image_;
const size_t buffer_index_;
+
+ // Texture could be nullptr if an empty backing is needed for testing.
Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture_;
// If d3d11_texture_ has a keyed mutex, it will be stored in
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_egl_image.cc b/chromium/gpu/command_buffer/service/shared_image_backing_egl_image.cc
index 62dca6c5f2f..c03cad6bf44 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_egl_image.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_egl_image.cc
@@ -355,7 +355,7 @@ void SharedImageBackingEglImage::MarkForDestruction() {
AutoLock auto_lock(this);
DCHECK(!have_context() || created_on_context_ == gl::g_current_gl_context);
- if (!have_context())
+ if (source_texture_holder_ && !have_context())
source_texture_holder_->MarkContextLost();
source_texture_holder_.reset();
}
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
index 44800465005..45558ea3b6c 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -240,6 +240,7 @@ class SharedImageRepresentationOverlayAHB
}
gl::GLImage* GetGLImage() override { return gl_image_; }
+ std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
gl::GLImage* gl_image_ = nullptr;
};
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
index 70585fea8f5..02d5d09af1c 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.cc
@@ -4,7 +4,10 @@
#include "gpu/command_buffer/service/shared_image_backing_factory_d3d.h"
+#include <d3d11_1.h>
+
#include "components/viz/common/resources/resource_format_utils.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/shared_image_backing_d3d.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gl/direct_composition_surface_win.h"
@@ -141,13 +144,9 @@ std::unique_ptr<SharedImageBacking> SharedImageBackingFactoryD3D::MakeBacking(
return nullptr;
}
} else if (shared_handle.IsValid()) {
- const HRESULT hr = d3d11_texture.As(&dxgi_keyed_mutex);
- if (FAILED(hr)) {
- DLOG(ERROR) << "Unable to QueryInterface for IDXGIKeyedMutex on texture "
- "with shared handle "
- << std::hex;
- return nullptr;
- }
+ // Keyed mutexes are required for Dawn interop but are not used
+ // for XR composition where fences are used instead.
+ d3d11_texture.As(&dxgi_keyed_mutex);
}
DCHECK(d3d11_texture);
@@ -380,15 +379,58 @@ SharedImageBackingFactoryD3D::CreateSharedImage(
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage) {
- NOTIMPLEMENTED();
- return nullptr;
+ // TODO: Add support for shared memory GMBs.
+ DCHECK_EQ(handle.type, gfx::DXGI_SHARED_HANDLE);
+ if (!handle.dxgi_handle.IsValid()) {
+ DLOG(ERROR) << "Invalid handle type passed to CreateSharedImage";
+ return nullptr;
+ }
+
+ if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat(size, format)) {
+ DLOG(ERROR) << "Invalid image size " << size.ToString() << " for "
+ << gfx::BufferFormatToString(format);
+ return nullptr;
+ }
+
+ Microsoft::WRL::ComPtr<ID3D11Device1> d3d11_device1;
+ HRESULT hr = d3d11_device_.As(&d3d11_device1);
+ if (FAILED(hr)) {
+ DLOG(ERROR) << "Failed to query for ID3D11Device1. Error: "
+ << logging::SystemErrorCodeToString(hr);
+ return nullptr;
+ }
+
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
+ hr = d3d11_device1->OpenSharedResource1(handle.dxgi_handle.Get(),
+ IID_PPV_ARGS(&d3d11_texture));
+ if (FAILED(hr)) {
+ DLOG(ERROR) << "Unable to open shared resource from DXGI handle. Error: "
+ << logging::SystemErrorCodeToString(hr);
+ return nullptr;
+ }
+
+ D3D11_TEXTURE2D_DESC desc;
+ d3d11_texture->GetDesc(&desc);
+
+ // TODO: Add checks for device specific limits.
+ if (desc.Width != static_cast<UINT>(size.width()) ||
+ desc.Height != static_cast<UINT>(size.height())) {
+ DLOG(ERROR)
+ << "Size passed to CreateSharedImage must match texture being opened";
+ return nullptr;
+ }
+
+ return MakeBacking(mailbox, viz::GetResourceFormat(format), size, color_space,
+ surface_origin, alpha_type, usage, /*swap_chain=*/nullptr,
+ /*buffer_index=*/0, std::move(d3d11_texture),
+ std::move(handle.dxgi_handle));
}
// Returns true if the specified GpuMemoryBufferType can be imported using
// this factory.
bool SharedImageBackingFactoryD3D::CanImportGpuMemoryBuffer(
gfx::GpuMemoryBufferType memory_buffer_type) {
- return false;
+ return (memory_buffer_type == gfx::DXGI_SHARED_HANDLE);
}
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.h b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.h
index 7abb0b0e0ac..3a8f9b8608f 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.h
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d.h
@@ -96,6 +96,10 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryD3D
bool CanImportGpuMemoryBuffer(
gfx::GpuMemoryBufferType memory_buffer_type) override;
+ Microsoft::WRL::ComPtr<ID3D11Device> GetDeviceForTesting() const {
+ return d3d11_device_;
+ }
+
private:
// Wraps the optional swap chain buffer (front buffer/back buffer) and texture
// into GLimage and creates a GL texture and stores it as gles2::Texture or as
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
index c5ed569920d..82025f30646 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_d3d_unittest.cc
@@ -11,6 +11,7 @@
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_context_state.h"
+#include "gpu/command_buffer/service/shared_image_backing_d3d.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/command_buffer/service/shared_image_manager.h"
#include "gpu/command_buffer/service/shared_image_representation.h"
@@ -846,5 +847,72 @@ TEST_F(SharedImageBackingFactoryD3DTest, SkiaAccessFirstFails) {
skia_representation->BeginScopedReadAccess(nullptr, nullptr);
EXPECT_EQ(scoped_read_access, nullptr);
}
+
+TEST_F(SharedImageBackingFactoryD3DTest, CreateSharedImageFromHandle) {
+ if (!IsD3DSharedImageSupported())
+ return;
+
+ EXPECT_TRUE(
+ shared_image_factory_->CanImportGpuMemoryBuffer(gfx::DXGI_SHARED_HANDLE));
+
+ Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device =
+ shared_image_factory_->GetDeviceForTesting();
+
+ const gfx::Size size(1, 1);
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = size.width();
+ desc.Height = size.height();
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags =
+ D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED;
+ Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
+ HRESULT hr = d3d11_device->CreateTexture2D(&desc, nullptr, &d3d11_texture);
+ ASSERT_EQ(hr, S_OK);
+
+ Microsoft::WRL::ComPtr<IDXGIResource1> dxgi_resource;
+ hr = d3d11_texture.As(&dxgi_resource);
+ ASSERT_EQ(hr, S_OK);
+
+ HANDLE shared_handle;
+ hr = dxgi_resource->CreateSharedHandle(
+ nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr,
+ &shared_handle);
+ ASSERT_EQ(hr, S_OK);
+
+ gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle;
+ gpu_memory_buffer_handle.dxgi_handle.Set(shared_handle);
+ gpu_memory_buffer_handle.type = gfx::DXGI_SHARED_HANDLE;
+
+ auto mailbox = Mailbox::GenerateForSharedImage();
+ const auto format = gfx::BufferFormat::RGBA_8888;
+ const auto color_space = gfx::ColorSpace::CreateSRGB();
+ const uint32_t usage = SHARED_IMAGE_USAGE_GLES2 | SHARED_IMAGE_USAGE_DISPLAY;
+ const gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
+ const GrSurfaceOrigin surface_origin = kTopLeft_GrSurfaceOrigin;
+ const SkAlphaType alpha_type = kPremul_SkAlphaType;
+ auto backing = shared_image_factory_->CreateSharedImage(
+ mailbox, 0, std::move(gpu_memory_buffer_handle), format, surface_handle,
+ size, color_space, surface_origin, alpha_type, usage);
+ ASSERT_NE(backing, nullptr);
+
+ EXPECT_EQ(backing->format(), viz::RGBA_8888);
+ EXPECT_EQ(backing->size(), size);
+ EXPECT_EQ(backing->color_space(), color_space);
+ EXPECT_EQ(backing->surface_origin(), surface_origin);
+ EXPECT_EQ(backing->alpha_type(), alpha_type);
+ EXPECT_EQ(backing->mailbox(), mailbox);
+
+ SharedImageBackingD3D* backing_d3d =
+ static_cast<SharedImageBackingD3D*>(backing.get());
+ EXPECT_EQ(backing_d3d->GetSharedHandle(), shared_handle);
+}
+
} // anonymous namespace
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h b/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h
index 0d1039554b4..c66613bc7c4 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h
@@ -22,6 +22,10 @@ class Size;
class ColorSpace;
} // namespace gfx
+namespace gl {
+class ProgressReporter;
+} // namespace gl
+
namespace gpu {
class SharedImageBacking;
class SharedImageBatchAccessManager;
@@ -43,7 +47,8 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryGLTexture
const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info,
ImageFactory* image_factory,
- SharedImageBatchAccessManager* batch_access_manager);
+ SharedImageBatchAccessManager* batch_access_manager,
+ gl::ProgressReporter* progress_reporter);
~SharedImageBackingFactoryGLTexture() override;
// SharedImageBackingFactory implementation.
@@ -170,6 +175,10 @@ class GPU_GLES2_EXPORT SharedImageBackingFactoryGLTexture
SharedImageBackingGLCommon::UnpackStateAttribs attribs;
GpuDriverBugWorkarounds workarounds_;
+ // Used to notify the watchdog before a buffer allocation in case it takes
+ // long.
+ gl::ProgressReporter* const progress_reporter_ = nullptr;
+
#if defined(OS_ANDROID)
SharedImageBatchAccessManager* batch_access_manager_ = nullptr;
#endif
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
index 0fbb0f60f1f..276317a3f26 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -29,6 +29,7 @@
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/config/gpu_test_config.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -44,6 +45,9 @@
#include "ui/gl/gl_image_stub.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/init/gl_factory.h"
+#include "ui/gl/progress_reporter.h"
+
+using testing::AtLeast;
namespace gpu {
namespace {
@@ -79,6 +83,15 @@ bool IsAndroid() {
#endif
}
+class MockProgressReporter : public gl::ProgressReporter {
+ public:
+ MockProgressReporter() = default;
+ ~MockProgressReporter() override = default;
+
+ // gl::ProgressReporter implementation.
+ MOCK_METHOD0(ReportProgress, void());
+};
+
class SharedImageBackingFactoryGLTextureTestBase
: public testing::TestWithParam<std::tuple<bool, viz::ResourceFormat>> {
public:
@@ -105,7 +118,7 @@ class SharedImageBackingFactoryGLTextureTestBase
preferences.use_passthrough_cmd_decoder = use_passthrough();
backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>(
preferences, workarounds, GpuFeatureInfo(), factory,
- shared_image_manager_->batch_access_manager());
+ shared_image_manager_->batch_access_manager(), &progress_reporter_);
memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr);
shared_image_representation_factory_ =
@@ -118,11 +131,31 @@ class SharedImageBackingFactoryGLTextureTestBase
gles2::PassthroughCommandDecoderSupported();
}
+ bool can_create_non_scanout_shared_image(viz::ResourceFormat format) const {
+ if (format == viz::ResourceFormat::BGRA_1010102 ||
+ format == viz::ResourceFormat::RGBA_1010102) {
+ return supports_ar30_ || supports_ab30_;
+ } else if (format == viz::ResourceFormat::ETC1) {
+ return supports_etc1_;
+ }
+ return true;
+ }
+
+ bool can_create_scanout_or_gmb_shared_image(
+ viz::ResourceFormat format) const {
+ if (format == viz::ResourceFormat::BGRA_1010102)
+ return supports_ar30_;
+ else if (format == viz::ResourceFormat::RGBA_1010102)
+ return supports_ab30_;
+ return true;
+ }
+
viz::ResourceFormat get_format() { return std::get<1>(GetParam()); }
GrDirectContext* gr_context() { return context_state_->gr_context(); }
protected:
+ ::testing::NiceMock<MockProgressReporter> progress_reporter_;
scoped_refptr<gl::GLSurface> surface_;
scoped_refptr<gl::GLContext> context_;
scoped_refptr<SharedContextState> context_state_;
@@ -213,6 +246,9 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, Basic) {
return;
}
+ const bool should_succeed = can_create_non_scanout_shared_image(get_format());
+ if (should_succeed)
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
auto mailbox = Mailbox::GenerateForSharedImage();
auto format = get_format();
gfx::Size size(256, 256);
@@ -225,12 +261,7 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, Basic) {
mailbox, format, surface_handle, size, color_space, surface_origin,
alpha_type, usage, false /* is_thread_safe */);
- // As long as either |chromium_image_ar30| or |chromium_image_ab30| is
- // enabled, we can create a non-scanout SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102.
- if ((format == viz::ResourceFormat::BGRA_1010102 ||
- format == viz::ResourceFormat::RGBA_1010102) &&
- !supports_ar30_ && !supports_ab30_) {
+ if (!should_succeed) {
EXPECT_FALSE(backing);
return;
}
@@ -347,6 +378,11 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, Image) {
bot_config.Matches("mac passthrough")) {
return;
}
+
+ const bool should_succeed =
+ can_create_scanout_or_gmb_shared_image(get_format());
+ if (should_succeed)
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
auto mailbox = Mailbox::GenerateForSharedImage();
auto format = get_format();
gfx::Size size(256, 256);
@@ -359,15 +395,12 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, Image) {
mailbox, format, surface_handle, size, color_space, surface_origin,
alpha_type, usage, false /* is_thread_safe */);
- // We can only create a scanout SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102 if the corresponding
- // |chromium_image_ar30| or |chromium_image_ab30| is enabled.
- if ((format == viz::ResourceFormat::BGRA_1010102 && !supports_ar30_) ||
- (format == viz::ResourceFormat::RGBA_1010102 && !supports_ab30_)) {
+ if (!should_succeed) {
EXPECT_FALSE(backing);
return;
}
ASSERT_TRUE(backing);
+ ::testing::Mock::VerifyAndClearExpectations(&progress_reporter_);
// Check clearing.
if (!backing->IsCleared()) {
@@ -472,6 +505,7 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, Image) {
if (!use_passthrough() &&
context_state_->feature_info()->feature_flags().ext_texture_rg) {
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
// Create a R-8 image texture, and check that the internal_format is that
// of the image (GL_RGBA for TextureImageFactory). This only matters for
// the validating decoder.
@@ -503,6 +537,9 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, InitialData) {
for (auto format :
{viz::ResourceFormat::RGBA_8888, viz::ResourceFormat::ETC1,
viz::ResourceFormat::BGRA_1010102, viz::ResourceFormat::RGBA_1010102}) {
+ const bool should_succeed = can_create_non_scanout_shared_image(format);
+ if (should_succeed)
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
auto mailbox = Mailbox::GenerateForSharedImage();
gfx::Size size(256, 256);
auto color_space = gfx::ColorSpace::CreateSRGB();
@@ -514,22 +551,11 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, InitialData) {
auto backing = backing_factory_->CreateSharedImage(
mailbox, format, size, color_space, surface_origin, alpha_type, usage,
initial_data);
-
- if (format == viz::ResourceFormat::ETC1 && !supports_etc1_) {
- EXPECT_FALSE(backing);
- continue;
- }
-
- // As long as either |chromium_image_ar30| or |chromium_image_ab30| is
- // enabled, we can create a non-scanout SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102.
- if ((format == viz::ResourceFormat::BGRA_1010102 ||
- format == viz::ResourceFormat::RGBA_1010102) &&
- !supports_ar30_ && !supports_ab30_) {
+ ::testing::Mock::VerifyAndClearExpectations(&progress_reporter_);
+ if (!should_succeed) {
EXPECT_FALSE(backing);
continue;
}
-
ASSERT_TRUE(backing);
EXPECT_TRUE(backing->IsCleared());
@@ -571,6 +597,10 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, InitialData) {
}
TEST_P(SharedImageBackingFactoryGLTextureTest, InitialDataImage) {
+ const bool should_succeed =
+ can_create_scanout_or_gmb_shared_image(get_format());
+ if (should_succeed)
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
auto mailbox = Mailbox::GenerateForSharedImage();
auto format = get_format();
gfx::Size size(256, 256);
@@ -582,12 +612,7 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, InitialDataImage) {
auto backing = backing_factory_->CreateSharedImage(
mailbox, format, size, color_space, surface_origin, alpha_type, usage,
initial_data);
-
- // We can only create a scanout SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102 if the corresponding
- // |chromium_image_ar30| or |chromium_image_ab30| is enabled.
- if ((format == viz::ResourceFormat::BGRA_1010102 && !supports_ar30_) ||
- (format == viz::ResourceFormat::RGBA_1010102 && !supports_ab30_)) {
+ if (!should_succeed) {
EXPECT_FALSE(backing);
return;
}
@@ -679,6 +704,9 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, InvalidSize) {
}
TEST_P(SharedImageBackingFactoryGLTextureTest, EstimatedSize) {
+ const bool should_succeed = can_create_non_scanout_shared_image(get_format());
+ if (should_succeed)
+ EXPECT_CALL(progress_reporter_, ReportProgress).Times(AtLeast(1));
auto mailbox = Mailbox::GenerateForSharedImage();
auto format = get_format();
gfx::Size size(256, 256);
@@ -691,12 +719,7 @@ TEST_P(SharedImageBackingFactoryGLTextureTest, EstimatedSize) {
mailbox, format, surface_handle, size, color_space, surface_origin,
alpha_type, usage, false /* is_thread_safe */);
- // As long as either |chromium_image_ar30| or |chromium_image_ab30| is
- // enabled, we can create a non-scanout SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102.
- if ((format == viz::ResourceFormat::BGRA_1010102 ||
- format == viz::ResourceFormat::RGBA_1010102) &&
- !supports_ar30_ && !supports_ab30_) {
+ if (!should_succeed) {
EXPECT_FALSE(backing);
return;
}
@@ -891,12 +914,7 @@ TEST_P(SharedImageBackingFactoryGLTextureWithGMBTest,
auto backing = backing_factory_->CreateSharedImage(
mailbox, kClientId, std::move(handle), format, kNullSurfaceHandle, size,
color_space, surface_origin, alpha_type, usage);
-
- // We can only create a GMB SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102 if the corresponding
- // |chromium_image_ar30| or |chromium_image_ab30| is enabled.
- if ((get_format() == viz::ResourceFormat::BGRA_1010102 && !supports_ar30_) ||
- (get_format() == viz::ResourceFormat::RGBA_1010102 && !supports_ab30_)) {
+ if (!can_create_scanout_or_gmb_shared_image(get_format())) {
EXPECT_FALSE(backing);
return;
}
@@ -952,12 +970,7 @@ TEST_P(SharedImageBackingFactoryGLTextureWithGMBTest,
auto backing = backing_factory_->CreateSharedImage(
mailbox, kClientId, std::move(handle), format, kNullSurfaceHandle, size,
color_space, surface_origin, alpha_type, usage);
-
- // We can only create a GMB SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102 if the corresponding
- // |chromium_image_ar30| or |chromium_image_ab30| is enabled.
- if ((get_format() == viz::ResourceFormat::BGRA_1010102 && !supports_ar30_) ||
- (get_format() == viz::ResourceFormat::RGBA_1010102 && !supports_ab30_)) {
+ if (!can_create_scanout_or_gmb_shared_image(get_format())) {
EXPECT_FALSE(backing);
return;
}
@@ -990,12 +1003,7 @@ TEST_P(SharedImageBackingFactoryGLTextureWithGMBTest,
auto backing = backing_factory_->CreateSharedImage(
mailbox, kClientId, std::move(handle), format, kNullSurfaceHandle, size,
color_space, surface_origin, alpha_type, usage);
-
- // We can only create a GMB SharedImage with format
- // viz::ResourceFormat::{BGRA,RGBA}_1010102 if the corresponding
- // |chromium_image_ar30| or |chromium_image_ab30| is enabled.
- if ((get_format() == viz::ResourceFormat::BGRA_1010102 && !supports_ar30_) ||
- (get_format() == viz::ResourceFormat::RGBA_1010102 && !supports_ab30_)) {
+ if (!can_create_scanout_or_gmb_shared_image(get_format())) {
EXPECT_FALSE(backing);
return;
}
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc b/chromium/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
index 5bf507cdbbe..8fc0c73f8a1 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_factory_iosurface_unittest.cc
@@ -67,7 +67,8 @@ class SharedImageBackingFactoryIOSurfaceTest : public testing::Test {
backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>(
preferences, workarounds, GpuFeatureInfo(), &image_factory_,
- shared_image_manager_.batch_access_manager());
+ shared_image_manager_.batch_access_manager(),
+ /*progress_reporter=*/nullptr);
memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr);
shared_image_representation_factory_ =
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_gl_common.h b/chromium/gpu/command_buffer/service/shared_image_backing_gl_common.h
index dc2dddcfc2b..6af656cf8b7 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_gl_common.h
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_gl_common.h
@@ -13,7 +13,7 @@ namespace gpu {
// Common helper functions for SharedImageBackingGLTexture and
// SharedImageBackingPassthroughGLImage.
-class SharedImageBackingGLCommon {
+class GPU_GLES2_EXPORT SharedImageBackingGLCommon {
public:
// These parameters are used to explicitly initialize a GL texture.
struct InitializeGLTextureParams {
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.cc b/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.cc
index c34decc537b..0318fd9d783 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.cc
@@ -17,6 +17,8 @@
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_fence.h"
#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/scoped_binders.h"
#include "ui/gl/trace_util.h"
#if defined(OS_MAC)
@@ -71,14 +73,20 @@ gles2::Texture* SharedImageRepresentationGLTextureImpl::GetTexture() {
}
bool SharedImageRepresentationGLTextureImpl::BeginAccess(GLenum mode) {
+ DCHECK(mode_ == 0);
+ mode_ = mode;
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess();
return true;
}
void SharedImageRepresentationGLTextureImpl::EndAccess() {
+ DCHECK(mode_ != 0);
+ GLenum current_mode = mode_;
+ mode_ = 0;
if (client_)
- return client_->SharedImageRepresentationGLTextureEndAccess();
+ return client_->SharedImageRepresentationGLTextureEndAccess(
+ current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
}
///////////////////////////////////////////////////////////////////////////////
@@ -109,14 +117,20 @@ SharedImageRepresentationGLTexturePassthroughImpl::GetTexturePassthrough() {
bool SharedImageRepresentationGLTexturePassthroughImpl::BeginAccess(
GLenum mode) {
+ DCHECK(mode_ == 0);
+ mode_ = mode;
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess();
return true;
}
void SharedImageRepresentationGLTexturePassthroughImpl::EndAccess() {
+ DCHECK(mode_ != 0);
+ GLenum current_mode = mode_;
+ mode_ = 0;
if (client_)
- return client_->SharedImageRepresentationGLTextureEndAccess();
+ return client_->SharedImageRepresentationGLTextureEndAccess(
+ current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
}
///////////////////////////////////////////////////////////////////////////////
@@ -189,7 +203,7 @@ void SharedImageRepresentationSkiaImpl::EndWriteAccess(
write_surface_ = nullptr;
if (client_)
- client_->SharedImageRepresentationGLTextureEndAccess();
+ client_->SharedImageRepresentationGLTextureEndAccess(false /* readonly */);
}
sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess(
@@ -206,7 +220,7 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess(
void SharedImageRepresentationSkiaImpl::EndReadAccess() {
if (client_)
- client_->SharedImageRepresentationGLTextureEndAccess();
+ client_->SharedImageRepresentationGLTextureEndAccess(true /* readonly */);
}
bool SharedImageRepresentationSkiaImpl::SupportsMultipleConcurrentReadAccess() {
@@ -244,6 +258,12 @@ gl::GLImage* SharedImageRepresentationOverlayImpl::GetGLImage() {
return gl_image_.get();
}
+std::unique_ptr<gfx::GpuFence>
+SharedImageRepresentationOverlayImpl::GetReadFence() {
+ auto* gl_backing = static_cast<SharedImageBackingGLImage*>(backing());
+ return gl_backing->GetLastWriteGpuFence();
+}
+
///////////////////////////////////////////////////////////////////////////////
// SharedImageBackingGLImage
@@ -357,6 +377,11 @@ GLuint SharedImageBackingGLImage::GetGLServiceId() const {
return 0;
}
+std::unique_ptr<gfx::GpuFence>
+SharedImageBackingGLImage::GetLastWriteGpuFence() {
+ return last_write_gl_fence_ ? last_write_gl_fence_->GetGpuFence() : nullptr;
+}
+
scoped_refptr<gfx::NativePixmap> SharedImageBackingGLImage::GetNativePixmap() {
return image_->GetNativePixmap();
}
@@ -561,7 +586,8 @@ bool SharedImageBackingGLImage::
return BindOrCopyImageIfNeeded();
}
-void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() {
+void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess(
+ bool readonly) {
#if defined(OS_MAC)
// If this image could potentially be shared with Metal via WebGPU, then flush
// the GL context to ensure Metal will see it.
@@ -569,6 +595,30 @@ void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() {
gl::GLApi* api = gl::g_current_gl_context;
api->glFlushFn();
}
+
+ // When SwANGLE is used as the GL implementation, we have to call
+ // ReleaseTexImage to signal an UnlockIOSurface call to sync the surface
+ // between the CPU and GPU. The next time this texture is accessed we will
+ // call BindTexImage to signal a LockIOSurface call before rendering to it via
+ // the CPU.
+ if (IsPassthrough() &&
+ gl::GetANGLEImplementation() == gl::ANGLEImplementation::kSwiftShader &&
+ image_->ShouldBindOrCopy() == gl::GLImage::BIND) {
+ const GLenum target = GetGLTarget();
+ gl::ScopedTextureBinder binder(target, passthrough_texture_->service_id());
+ if (!passthrough_texture_->is_bind_pending()) {
+ image_->ReleaseTexImage(target);
+ image_bind_or_copy_needed_ = true;
+ }
+ }
+#else
+ // If the image will be used for an overlay, we insert a fence that can be
+ // used by OutputPresenter to synchronize image writes with presentation.
+ if (!readonly && usage() & SHARED_IMAGE_USAGE_SCANOUT &&
+ gl::GLFence::IsGpuFenceSupported()) {
+ last_write_gl_fence_ = gl::GLFence::CreateForGpuFence();
+ DCHECK(last_write_gl_fence_);
+ }
#endif
}
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.h b/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.h
index 9dcb41bfe59..39a7b45a013 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.h
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_gl_image.h
@@ -7,6 +7,8 @@
#include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image_backing_gl_common.h"
+#include "gpu/gpu_gles2_export.h"
+#include "ui/gl/gl_fence.h"
namespace gpu {
@@ -15,7 +17,7 @@ namespace gpu {
class SharedImageRepresentationGLTextureClient {
public:
virtual bool SharedImageRepresentationGLTextureBeginAccess() = 0;
- virtual void SharedImageRepresentationGLTextureEndAccess() = 0;
+ virtual void SharedImageRepresentationGLTextureEndAccess(bool readonly) = 0;
virtual void SharedImageRepresentationGLTextureRelease(bool have_context) = 0;
};
@@ -40,6 +42,7 @@ class SharedImageRepresentationGLTextureImpl
SharedImageRepresentationGLTextureClient* const client_ = nullptr;
gles2::Texture* texture_;
+ GLenum mode_ = 0;
};
// Representation of a SharedImageBackingGLTexture or
@@ -68,6 +71,7 @@ class SharedImageRepresentationGLTexturePassthroughImpl
SharedImageRepresentationGLTextureClient* const client_ = nullptr;
scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
+ GLenum mode_ = 0;
};
// Skia representation for both SharedImageBackingGLCommon.
@@ -130,6 +134,7 @@ class SharedImageRepresentationOverlayImpl
bool BeginReadAccess() override;
void EndReadAccess() override;
gl::GLImage* GetGLImage() override;
+ std::unique_ptr<gfx::GpuFence> GetReadFence() override;
scoped_refptr<gl::GLImage> gl_image_;
};
@@ -137,7 +142,7 @@ class SharedImageRepresentationOverlayImpl
// Implementation of SharedImageBacking that creates a GL Texture that is backed
// by a GLImage and stores it as a gles2::Texture. Can be used with the legacy
// mailbox implementation.
-class SharedImageBackingGLImage
+class GPU_GLES2_EXPORT SharedImageBackingGLImage
: public SharedImageBacking,
public SharedImageRepresentationGLTextureClient {
public:
@@ -162,6 +167,7 @@ class SharedImageBackingGLImage
GLenum GetGLTarget() const;
GLuint GetGLServiceId() const;
+ std::unique_ptr<gfx::GpuFence> GetLastWriteGpuFence();
private:
// SharedImageBacking:
@@ -197,7 +203,7 @@ class SharedImageBackingGLImage
// SharedImageRepresentationGLTextureClient:
bool SharedImageRepresentationGLTextureBeginAccess() override;
- void SharedImageRepresentationGLTextureEndAccess() override;
+ void SharedImageRepresentationGLTextureEndAccess(bool readonly) override;
void SharedImageRepresentationGLTextureRelease(bool have_context) override;
bool IsPassthrough() const { return is_passthrough_; }
@@ -227,6 +233,7 @@ class SharedImageBackingGLImage
scoped_refptr<gles2::TexturePassthrough> passthrough_texture_;
sk_sp<SkPromiseImageTexture> cached_promise_texture_;
+ std::unique_ptr<gl::GLFence> last_write_gl_fence_;
base::WeakPtrFactory<SharedImageBackingGLImage> weak_factory_;
};
diff --git a/chromium/gpu/command_buffer/service/shared_image_backing_gl_texture.cc b/chromium/gpu/command_buffer/service/shared_image_backing_gl_texture.cc
index bb72877968e..354d49401d1 100644
--- a/chromium/gpu/command_buffer/service/shared_image_backing_gl_texture.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_backing_gl_texture.cc
@@ -44,6 +44,7 @@
#include "ui/gl/gl_image_shared_memory.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_version_info.h"
+#include "ui/gl/progress_reporter.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/shared_gl_fence_egl.h"
#include "ui/gl/trace_util.h"
@@ -75,11 +76,13 @@ SharedImageBackingFactoryGLTexture::SharedImageBackingFactoryGLTexture(
const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info,
ImageFactory* image_factory,
- SharedImageBatchAccessManager* batch_access_manager)
+ SharedImageBatchAccessManager* batch_access_manager,
+ gl::ProgressReporter* progress_reporter)
: use_passthrough_(gpu_preferences.use_passthrough_cmd_decoder &&
gles2::PassthroughCommandDecoderSupported()),
image_factory_(image_factory),
- workarounds_(workarounds) {
+ workarounds_(workarounds),
+ progress_reporter_(progress_reporter) {
#if defined(OS_ANDROID)
batch_access_manager_ = batch_access_manager;
#endif
@@ -424,7 +427,9 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
const bool use_buffer = usage & SHARED_IMAGE_USAGE_SCANOUT;
#endif
if (use_buffer && !format_info.allow_scanout) {
- LOG(ERROR) << "CreateSharedImage: SCANOUT shared images unavailable";
+ LOG(ERROR) << "CreateSharedImage: SCANOUT shared images unavailable. "
+ "Buffer format= "
+ << gfx::BufferFormatToString(format_info.buffer_format);
return nullptr;
}
@@ -503,13 +508,22 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
// the internal format in the LevelInfo. https://crbug.com/628064
GLuint level_info_internal_format = format_info.gl_format;
bool is_cleared = false;
+
+ // |scoped_progress_reporter| will notify |progress_reporter_| upon
+ // construction and destruction. We limit the scope so that progress is
+ // reported immediately after allocation/upload and before other GL
+ // operations.
if (use_buffer) {
- image = image_factory_->CreateAnonymousImage(
- size, format_info.buffer_format, gfx::BufferUsage::SCANOUT,
- surface_handle, &is_cleared);
+ {
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
+ image = image_factory_->CreateAnonymousImage(
+ size, format_info.buffer_format, gfx::BufferUsage::SCANOUT,
+ surface_handle, &is_cleared);
+ }
// Scanout images have different constraints than GL images and might fail
// to allocate even if GL images can be created.
if (!image) {
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
// TODO(dcastagna): Use BufferUsage::GPU_READ_WRITE instead
// BufferUsage::GPU_READ once we add it.
image = image_factory_->CreateAnonymousImage(
@@ -544,6 +558,7 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
image, mailbox, format, size, color_space, surface_origin, alpha_type,
usage, params, attribs, use_passthrough_);
if (!pixel_data.empty()) {
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
result->InitializePixels(format_info.adjusted_format, format_info.gl_type,
pixel_data.data());
}
@@ -559,12 +574,16 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
api->glBindTextureFn(target, result->GetGLServiceId());
if (format_info.supports_storage) {
- api->glTexStorage2DEXTFn(target, 1, format_info.storage_internal_format,
- size.width(), size.height());
+ {
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
+ api->glTexStorage2DEXTFn(target, 1, format_info.storage_internal_format,
+ size.width(), size.height());
+ }
if (!pixel_data.empty()) {
ScopedResetAndRestoreUnpackState scoped_unpack_state(
api, attribs, true /* uploading_data */);
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
api->glTexSubImage2DFn(target, 0, 0, 0, size.width(), size.height(),
format_info.adjusted_format, format_info.gl_type,
pixel_data.data());
@@ -572,12 +591,14 @@ SharedImageBackingFactoryGLTexture::CreateSharedImageInternal(
} else if (format_info.is_compressed) {
ScopedResetAndRestoreUnpackState scoped_unpack_state(api, attribs,
!pixel_data.empty());
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
api->glCompressedTexImage2DFn(
target, 0, format_info.image_internal_format, size.width(),
size.height(), 0, pixel_data.size(), pixel_data.data());
} else {
ScopedResetAndRestoreUnpackState scoped_unpack_state(api, attribs,
!pixel_data.empty());
+ gl::ScopedProgressReporter scoped_progress_reporter(progress_reporter_);
api->glTexImage2DFn(target, 0, format_info.image_internal_format,
size.width(), size.height(), 0,
format_info.adjusted_format, format_info.gl_type,
diff --git a/chromium/gpu/command_buffer/service/shared_image_factory.cc b/chromium/gpu/command_buffer/service/shared_image_factory.cc
index 6b42ed63b84..c671ee2f0b4 100644
--- a/chromium/gpu/command_buffer/service/shared_image_factory.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_factory.cc
@@ -100,7 +100,9 @@ SharedImageFactory::SharedImageFactory(
if (use_gl) {
gl_backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>(
gpu_preferences, workarounds, gpu_feature_info, image_factory,
- shared_image_manager->batch_access_manager());
+ shared_image_manager->batch_access_manager(),
+ shared_context_state_ ? shared_context_state_->progress_reporter()
+ : nullptr);
}
// TODO(ccameron): This block of code should be changed to a switch on
@@ -341,7 +343,8 @@ bool SharedImageFactory::RegisterSysmemBufferCollection(
gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ bool register_with_image_pipe) {
decltype(buffer_collections_)::iterator it;
bool inserted;
std::tie(it, inserted) =
@@ -362,10 +365,10 @@ bool SharedImageFactory::RegisterSysmemBufferCollection(
VkDevice device =
vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice();
DCHECK(device != VK_NULL_HANDLE);
- it->second =
- vulkan_context_provider_->GetVulkanImplementation()
- ->RegisterSysmemBufferCollection(device, id, std::move(token), format,
- usage, gfx::Size(), 0);
+ it->second = vulkan_context_provider_->GetVulkanImplementation()
+ ->RegisterSysmemBufferCollection(
+ device, id, std::move(token), format, usage, gfx::Size(),
+ 0, register_with_image_pipe);
return true;
}
diff --git a/chromium/gpu/command_buffer/service/shared_image_factory.h b/chromium/gpu/command_buffer/service/shared_image_factory.h
index 6534c88271a..f4668e110bf 100644
--- a/chromium/gpu/command_buffer/service/shared_image_factory.h
+++ b/chromium/gpu/command_buffer/service/shared_image_factory.h
@@ -111,7 +111,8 @@ class GPU_GLES2_EXPORT SharedImageFactory {
bool RegisterSysmemBufferCollection(gfx::SysmemBufferCollectionId id,
zx::channel token,
gfx::BufferFormat format,
- gfx::BufferUsage usage);
+ gfx::BufferUsage usage,
+ bool register_with_image_pipe);
bool ReleaseSysmemBufferCollection(gfx::SysmemBufferCollectionId id);
#endif // defined(OS_FUCHSIA)
diff --git a/chromium/gpu/command_buffer/service/shared_image_representation.cc b/chromium/gpu/command_buffer/service/shared_image_representation.cc
index 55d762979e8..e5ddefc7f4a 100644
--- a/chromium/gpu/command_buffer/service/shared_image_representation.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_representation.cc
@@ -8,6 +8,7 @@
#include "gpu/command_buffer/service/texture_manager.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrDirectContext.h"
+#include "ui/gl/gl_fence.h"
#if defined(OS_ANDROID)
#include "base/android/scoped_hardware_buffer_fence_sync.h"
@@ -227,8 +228,15 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkia::BeginReadAccess(
SharedImageRepresentationOverlay::ScopedReadAccess::ScopedReadAccess(
util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation,
- gl::GLImage* gl_image)
- : ScopedAccessBase(representation), gl_image_(gl_image) {}
+ gl::GLImage* gl_image,
+ std::unique_ptr<gfx::GpuFence> fence)
+ : ScopedAccessBase(representation),
+ gl_image_(gl_image),
+ fence_(std::move(fence)) {}
+
+SharedImageRepresentationOverlay::ScopedReadAccess::~ScopedReadAccess() {
+ representation()->EndReadAccess();
+}
std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess>
SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) {
@@ -244,7 +252,7 @@ SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) {
return std::make_unique<ScopedReadAccess>(
util::PassKey<SharedImageRepresentationOverlay>(), this,
- needs_gl_image ? GetGLImage() : nullptr);
+ needs_gl_image ? GetGLImage() : nullptr, GetReadFence());
}
SharedImageRepresentationDawn::ScopedAccess::ScopedAccess(
diff --git a/chromium/gpu/command_buffer/service/shared_image_representation.h b/chromium/gpu/command_buffer/service/shared_image_representation.h
index 626f610a4c0..2ca5a057479 100644
--- a/chromium/gpu/command_buffer/service/shared_image_representation.h
+++ b/chromium/gpu/command_buffer/service/shared_image_representation.h
@@ -392,20 +392,22 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
- class ScopedReadAccess
+ class GPU_GLES2_EXPORT ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationOverlay> {
public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation,
- gl::GLImage* gl_image);
- ~ScopedReadAccess() { representation()->EndReadAccess(); }
+ gl::GLImage* gl_image,
+ std::unique_ptr<gfx::GpuFence> fence);
+ ~ScopedReadAccess();
- gl::GLImage* gl_image() const {
- return gl_image_;
- }
+ gl::GLImage* gl_image() const { return gl_image_; }
+
+ std::unique_ptr<gfx::GpuFence> TakeFence() { return std::move(fence_); }
private:
gl::GLImage* gl_image_;
+ std::unique_ptr<gfx::GpuFence> fence_;
};
#if defined(OS_ANDROID)
@@ -426,6 +428,9 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
// TODO(penghuang): Refactor it to not depend on GL.
// Get the backing as GLImage for GLSurface::ScheduleOverlayPlane.
virtual gl::GLImage* GetGLImage() = 0;
+ // Optionally returns a fence to synchronize writes on the SharedImage with
+ // overlay presentation.
+ virtual std::unique_ptr<gfx::GpuFence> GetReadFence() = 0;
};
// An interface that allows a SharedImageBacking to hold a reference to VA-API
diff --git a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc
index 9be3bd1599e..afde8952d16 100644
--- a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.cc
@@ -132,4 +132,27 @@ void SharedImageRepresentationDawnD3D::EndAccess() {
}
#endif // BUILDFLAG(USE_DAWN)
+SharedImageRepresentationOverlayD3D::SharedImageRepresentationOverlayD3D(
+ SharedImageManager* manager,
+ SharedImageBacking* backing,
+ MemoryTypeTracker* tracker)
+ : SharedImageRepresentationOverlay(manager, backing, tracker) {}
+
+bool SharedImageRepresentationOverlayD3D::BeginReadAccess() {
+ // Note: only the DX11 video decoder uses this overlay and does not need to
+ // synchronize read access from different devices.
+ return true;
+}
+
+void SharedImageRepresentationOverlayD3D::EndReadAccess() {}
+
+gl::GLImage* SharedImageRepresentationOverlayD3D::GetGLImage() {
+ return static_cast<SharedImageBackingD3D*>(backing())->GetGLImage();
+}
+
+std::unique_ptr<gfx::GpuFence>
+SharedImageRepresentationOverlayD3D::GetReadFence() {
+ return nullptr;
+}
+
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h
index 72e41f183a1..164b974431d 100644
--- a/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h
+++ b/chromium/gpu/command_buffer/service/shared_image_representation_d3d.h
@@ -20,6 +20,8 @@
namespace gpu {
+class SharedImageBackingD3D;
+
// Representation of a SharedImageBackingD3D as a GL TexturePassthrough.
class SharedImageRepresentationGLTexturePassthroughD3D
: public SharedImageRepresentationGLTexturePassthrough {
@@ -65,5 +67,22 @@ class SharedImageRepresentationDawnD3D : public SharedImageRepresentationDawn {
};
#endif // BUILDFLAG(USE_DAWN)
+// Representation of a SharedImageBackingD3D as an overlay.
+class SharedImageRepresentationOverlayD3D
+ : public SharedImageRepresentationOverlay {
+ public:
+ SharedImageRepresentationOverlayD3D(SharedImageManager* manager,
+ SharedImageBacking* backing,
+ MemoryTypeTracker* tracker);
+ ~SharedImageRepresentationOverlayD3D() override = default;
+
+ private:
+ bool BeginReadAccess() override;
+ void EndReadAccess() override;
+
+ gl::GLImage* GetGLImage() override;
+ std::unique_ptr<gfx::GpuFence> GetReadFence() override;
+};
+
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_D3D_H_
diff --git a/chromium/gpu/command_buffer/service/shared_image_video.cc b/chromium/gpu/command_buffer/service/shared_image_video.cc
index 6b7ebfe39c2..9cb70be0488 100644
--- a/chromium/gpu/command_buffer/service/shared_image_video.cc
+++ b/chromium/gpu/command_buffer/service/shared_image_video.cc
@@ -433,6 +433,8 @@ class SharedImageRepresentationOverlayVideo
return stream_image_.get();
}
+ std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
+
void NotifyOverlayPromotion(bool promotion,
const gfx::Rect& bounds) override {
stream_image_->NotifyOverlayPromotion(promotion, bounds);
diff --git a/chromium/gpu/command_buffer/service/test_shared_image_backing.cc b/chromium/gpu/command_buffer/service/test_shared_image_backing.cc
index ab09c2f9ec6..d51e7bd7f7b 100644
--- a/chromium/gpu/command_buffer/service/test_shared_image_backing.cc
+++ b/chromium/gpu/command_buffer/service/test_shared_image_backing.cc
@@ -118,6 +118,7 @@ class TestSharedImageRepresentationOverlay
bool BeginReadAccess() override { return true; }
void EndReadAccess() override {}
gl::GLImage* GetGLImage() override { return nullptr; }
+ std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
#if defined(OS_ANDROID)
void NotifyOverlayPromotion(bool promotion,
diff --git a/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc b/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc
index b6eb2d3eea7..bacd6d560e7 100644
--- a/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc
+++ b/chromium/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -648,6 +648,13 @@ error::Error WebGPUDecoderImpl::InitDawnDeviceAndSetWireServer(
if (request_device_properties.textureCompressionBC) {
device_descriptor.requiredExtensions.push_back("texture_compression_bc");
}
+ if (request_device_properties.shaderFloat16) {
+ device_descriptor.requiredExtensions.push_back("shader_float16");
+ }
+
+ if (request_device_properties.timestampQuery) {
+ device_descriptor.requiredExtensions.push_back("timestamp_query");
+ }
WGPUDevice wgpu_device =
dawn_adapters_[requested_adapter_index].CreateDevice(&device_descriptor);
diff --git a/chromium/gpu/command_buffer/service/wrapped_sk_image.cc b/chromium/gpu/command_buffer/service/wrapped_sk_image.cc
index 3db30402eef..0f5d11c289d 100644
--- a/chromium/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/chromium/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -56,7 +56,7 @@ class WrappedSkImage : public ClearTrackingSharedImageBacking {
context_state_->EraseCachedSkSurface(this);
if (backend_texture_.isValid())
- DeleteGrBackendTexture(context_state_, &backend_texture_);
+ DeleteGrBackendTexture(context_state_.get(), &backend_texture_);
DCHECK(context_state_->context_lost() ||
context_state_->IsCurrent(nullptr));
@@ -155,7 +155,7 @@ class WrappedSkImage : public ClearTrackingSharedImageBacking {
SkAlphaType alpha_type,
uint32_t usage,
size_t estimated_size,
- SharedContextState* context_state)
+ scoped_refptr<SharedContextState> context_state)
: ClearTrackingSharedImageBacking(mailbox,
format,
size,
@@ -165,7 +165,7 @@ class WrappedSkImage : public ClearTrackingSharedImageBacking {
usage,
estimated_size,
false /* is_thread_safe */),
- context_state_(context_state) {
+ context_state_(std::move(context_state)) {
DCHECK(!!context_state_);
}
@@ -190,7 +190,9 @@ class WrappedSkImage : public ClearTrackingSharedImageBacking {
if (context_state_->context_lost())
return false;
- DCHECK(context_state_->IsCurrent(nullptr));
+ // MakeCurrent to avoid destroying another client's state because Skia may
+ // change GL state to create and upload textures (crbug.com/1095679).
+ context_state_->MakeCurrent(nullptr);
context_state_->set_need_context_state_reset(true);
#if BUILDFLAG(ENABLE_VULKAN)
@@ -283,7 +285,7 @@ class WrappedSkImage : public ClearTrackingSharedImageBacking {
return true;
}
- SharedContextState* const context_state_;
+ scoped_refptr<SharedContextState> context_state_;
GrBackendTexture backend_texture_;
sk_sp<SkPromiseImageTexture> promise_texture_;
@@ -355,8 +357,9 @@ class WrappedSkImageRepresentation : public SharedImageRepresentationSkia {
} // namespace
-WrappedSkImageFactory::WrappedSkImageFactory(SharedContextState* context_state)
- : context_state_(context_state) {}
+WrappedSkImageFactory::WrappedSkImageFactory(
+ scoped_refptr<SharedContextState> context_state)
+ : context_state_(std::move(context_state)) {}
WrappedSkImageFactory::~WrappedSkImageFactory() = default;
diff --git a/chromium/gpu/command_buffer/service/wrapped_sk_image.h b/chromium/gpu/command_buffer/service/wrapped_sk_image.h
index b0b8bc9fdc3..659ce4d1d1f 100644
--- a/chromium/gpu/command_buffer/service/wrapped_sk_image.h
+++ b/chromium/gpu/command_buffer/service/wrapped_sk_image.h
@@ -24,7 +24,8 @@ namespace raster {
class GPU_GLES2_EXPORT WrappedSkImageFactory
: public gpu::SharedImageBackingFactory {
public:
- explicit WrappedSkImageFactory(SharedContextState* context_state);
+ explicit WrappedSkImageFactory(
+ scoped_refptr<SharedContextState> context_state);
~WrappedSkImageFactory() override;
// SharedImageBackingFactory implementation:
@@ -62,7 +63,7 @@ class GPU_GLES2_EXPORT WrappedSkImageFactory
gfx::GpuMemoryBufferType memory_buffer_type) override;
private:
- SharedContextState* const context_state_;
+ scoped_refptr<SharedContextState> context_state_;
DISALLOW_COPY_AND_ASSIGN(WrappedSkImageFactory);
};