Commit 76dfd502 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Implement TexStorage2DImage

This is supported on OSX and was triggered when running with
--enable-oop-rasterization and --enable-raster-decoder. This CL is
necessary before we can land http://crrev.com/c/1031012

Notable changes:

- shuffled some code from compositor_util to gpu_memory_support so that
  we can use it in a lower layer

- add proper gpu memory buffer support to InProcCmdBuffer

- add a raster_in_process_context_tests to give us some basic code
  coverage

- copy-pasta from GLES2DecoderImpl to RasterDecoderImpl to implement
  TexStorage2DImage

Bug: 789238
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Iee75adbfd922ab0c94f2e563fe4fbdbf4c84f231
Reviewed-on: https://chromium-review.googlesource.com/964894Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Commit-Queue: Jonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555825}
parent ffd84f41
......@@ -5,8 +5,9 @@
#include "content/browser/gpu/compositor_util.h"
#include <stddef.h>
#include <memory>
#include <algorithm>
#include <memory>
#include <utility>
#include "base/command_line.h"
......@@ -25,7 +26,6 @@
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/config/gpu_blacklist.h"
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
......@@ -477,21 +477,4 @@ std::vector<std::string> GetDriverBugWorkaroundsForHardwareGpu() {
return GetDriverBugWorkaroundsImpl(GpuFeatureInfoType::kForHardwareGpu);
}
std::vector<gfx::BufferUsageAndFormat>
CreateBufferUsageAndFormatExceptionList() {
std::vector<gfx::BufferUsageAndFormat> usage_format_list;
for (int usage_idx = 0; usage_idx <= static_cast<int>(gfx::BufferUsage::LAST);
++usage_idx) {
gfx::BufferUsage usage = static_cast<gfx::BufferUsage>(usage_idx);
for (int format_idx = 0;
format_idx <= static_cast<int>(gfx::BufferFormat::LAST);
++format_idx) {
gfx::BufferFormat format = static_cast<gfx::BufferFormat>(format_idx);
if (gpu::GetImageNeedsPlatformSpecificTextureTarget(format, usage))
usage_format_list.push_back(gfx::BufferUsageAndFormat(usage, format));
}
}
return usage_format_list;
}
} // namespace content
......@@ -6,11 +6,11 @@
#define CONTENT_BROWSER_GPU_COMPOSITOR_UTIL_H_
#include <memory>
#include <string>
#include <vector>
#include "base/values.h"
#include "content/common/content_export.h"
#include "ui/gfx/buffer_types.h"
namespace content {
......@@ -52,11 +52,6 @@ GetFeatureStatusForHardwareGpu();
CONTENT_EXPORT std::unique_ptr<base::ListValue> GetProblemsForHardwareGpu();
CONTENT_EXPORT std::vector<std::string> GetDriverBugWorkaroundsForHardwareGpu();
// Populate a list of buffer usage/format for which a per platform specific
// texture target must be used instead of GL_TEXTURE_2D.
CONTENT_EXPORT std::vector<gfx::BufferUsageAndFormat>
CreateBufferUsageAndFormatExceptionList();
} // namespace content
#endif // CONTENT_BROWSER_GPU_COMPOSITOR_UTIL_H_
......@@ -24,7 +24,6 @@
#include "cc/base/switches.h"
#include "components/viz/common/features.h"
#include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
#include "content/browser/gpu/compositor_util.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/gpu_data_manager_observer.h"
......@@ -45,6 +44,7 @@
#include "gpu/config/software_rendering_list_autogen.h"
#include "gpu/ipc/common/gpu_preferences_util.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/ipc/host/shader_disk_cache.h"
#include "media/media_buildflags.h"
#include "ui/base/ui_base_switches.h"
......@@ -195,7 +195,7 @@ void DisplayReconfigCallback(CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void* gpu_data_manager) {
if (flags == kCGDisplayBeginConfigurationFlag)
return; // This call contains no information about the display change
return; // This call contains no information about the display change
GpuDataManagerImpl* manager =
reinterpret_cast<GpuDataManagerImpl*>(gpu_data_manager);
......@@ -261,7 +261,7 @@ void UpdateGpuInfoOnIO(const gpu::GPUInfo& gpu_info) {
gpu_info));
}
} // namespace anonymous
} // anonymous namespace
void GpuDataManagerImplPrivate::BlacklistWebGLForTesting() {
// This function is for testing only, so disable histograms.
......@@ -538,7 +538,6 @@ void GpuDataManagerImplPrivate::AppendGpuCommandLine(
command_line->AppendSwitch(switches::kOverrideUseSoftwareGLForTests);
}
#endif // !OS_MACOSX
}
void GpuDataManagerImplPrivate::UpdateGpuPreferences(
......@@ -560,7 +559,7 @@ void GpuDataManagerImplPrivate::UpdateGpuPreferences(
gpu::ShaderDiskCache::CacheSizeBytes();
gpu_preferences->texture_target_exception_list =
CreateBufferUsageAndFormatExceptionList();
gpu::CreateBufferUsageAndFormatExceptionList();
}
void GpuDataManagerImplPrivate::DisableHardwareAcceleration() {
......
......@@ -253,6 +253,7 @@ test("gl_tests") {
"//gpu/command_buffer/client:raster",
"//gpu/command_buffer/common:gles2_utils",
"//gpu/ipc:gl_in_process_context",
"//gpu/ipc/host",
"//gpu/ipc/service",
"//testing/gmock",
"//testing/gtest",
......
......@@ -45,6 +45,7 @@
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/command_buffer/service/gles2_cmd_copy_tex_image.h"
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/image_factory.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/indexed_buffer_binding_host.h"
#include "gpu/command_buffer/service/logger.h"
......@@ -62,6 +63,7 @@
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/ipc/color/gfx_param_traits.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_gl_api_implementation.h"
......@@ -505,9 +507,7 @@ class RasterDecoderImpl final : public RasterDecoder,
void TexStorage2DImage(TextureRef* texture_ref,
const TextureMetadata& texture_metadata,
GLsizei width,
GLsizei height) {
NOTIMPLEMENTED();
}
GLsizei height);
void TexStorage2D(TextureRef* texture_ref,
const TextureMetadata& texture_metadata,
GLint levels,
......@@ -2106,6 +2106,74 @@ void RasterDecoderImpl::DoProduceTextureDirect(GLuint client_id,
group_->mailbox_manager()->ProduceTexture(mailbox, produced);
}
void RasterDecoderImpl::TexStorage2DImage(
TextureRef* texture_ref,
const TextureMetadata& texture_metadata,
GLsizei width,
GLsizei height) {
TRACE_EVENT2("gpu", "RasterDecoderImpl::TexStorage2DImage", "width", width,
"height", height);
gpu::gles2::Texture* texture = texture_ref->texture();
if (texture->IsImmutable()) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImage",
"texture is immutable");
return;
}
gfx::BufferFormat buffer_format =
viz::BufferFormat(texture_metadata.format());
switch (buffer_format) {
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::RGBA_F16:
case gfx::BufferFormat::R_8:
break;
default:
LOCAL_SET_GL_ERROR(GL_INVALID_ENUM, "glTexStorage2DImage",
"Invalid buffer format");
return;
}
GLint untyped_format = viz::GLDataFormat(texture_metadata.format());
if (!GetContextGroup()->image_factory()) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImage",
"Cannot create GL image");
return;
}
bool is_cleared = false;
scoped_refptr<gl::GLImage> image =
GetContextGroup()->image_factory()->CreateAnonymousImage(
gfx::Size(width, height), buffer_format, gfx::BufferUsage::SCANOUT,
untyped_format, &is_cleared);
ScopedTextureBinder binder(&state_, texture_manager(), texture_ref,
texture_metadata.target());
if (!texture_manager()->ValidForTarget(texture_metadata.target(), 0, width,
height, 1)) {
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexStorage2DImage",
"dimensions out of range");
return;
}
if (!image || !image->BindTexImage(texture_metadata.target())) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glTexStorage2DImage",
"Failed to create or bind GL Image");
return;
}
gfx::Rect cleared_rect;
if (is_cleared)
cleared_rect = gfx::Rect(width, height);
texture_manager()->SetLevelInfo(texture_ref, texture_metadata.target(), 0,
image->GetInternalFormat(), width, height, 1,
0, image->GetInternalFormat(),
GL_UNSIGNED_BYTE, cleared_rect);
texture_manager()->SetLevelImage(texture_ref, texture_metadata.target(), 0,
image.get(), gpu::gles2::Texture::BOUND);
}
void RasterDecoderImpl::TexStorage2D(TextureRef* texture_ref,
const TextureMetadata& texture_metadata,
GLint levels,
......@@ -2532,6 +2600,7 @@ void RasterDecoderImpl::DoCopySubTexture(GLuint source_id,
source_level)) {
GLfloat transform_matrix[16];
image->GetTextureMatrix(transform_matrix);
copy_texture_chromium_->DoCopySubTextureWithTransform(
this, source_target, source_texture->service_id(), source_level,
source_internal_format, dest_target, dest_texture->service_id(),
......
......@@ -36,6 +36,7 @@ component("gl_in_process_context") {
"//gpu/config",
"//gpu/ipc/client",
"//gpu/ipc/common:surface_handle_type",
"//gpu/ipc/host",
"//gpu/ipc/service",
"//gpu/skia_bindings:skia_bindings",
"//ui/gfx",
......
......@@ -7,10 +7,13 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "components/viz/test/test_gpu_memory_buffer_manager.h"
#include "gpu/command_buffer/client/raster_implementation.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/ipc/raster_in_process_context.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/color_space.h"
......@@ -39,7 +42,7 @@ class RasterInProcessCommandBufferTest : public ::testing::TestWithParam<bool> {
auto result = context->Initialize(
/*service=*/nullptr, attributes, SharedMemoryLimits(),
gpu_memory_buffer_manager_.get(),
/*image_factory=*/nullptr,
gpu_memory_buffer_factory_->AsImageFactory(),
/*gpu_channel_manager_delegate=*/nullptr,
base::ThreadTaskRunnerHandle::Get());
DCHECK_EQ(result, ContextResult::kSuccess);
......@@ -47,6 +50,7 @@ class RasterInProcessCommandBufferTest : public ::testing::TestWithParam<bool> {
}
void SetUp() override {
gpu_memory_buffer_factory_ = GpuMemoryBufferFactory::CreateNativeType();
gpu_memory_buffer_manager_ =
std::make_unique<viz::TestGpuMemoryBufferManager>();
context_ = CreateRasterInProcessContext();
......@@ -56,13 +60,13 @@ class RasterInProcessCommandBufferTest : public ::testing::TestWithParam<bool> {
void TearDown() override {
context_.reset();
gpu_memory_buffer_manager_.reset();
gpu_memory_buffer_factory_.reset();
}
protected:
raster::RasterInterface* ri_; // not owned
std::unique_ptr<GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
std::unique_ptr<GpuMemoryBufferManager> gpu_memory_buffer_manager_;
private:
std::unique_ptr<RasterInProcessContext> context_;
};
......@@ -115,6 +119,43 @@ TEST_P(RasterInProcessCommandBufferTest, SetColorSpaceMetadata) {
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError());
}
TEST_P(RasterInProcessCommandBufferTest, TexStorage2DImage) {
// Check for GPU and driver support
if (!context_->GetCapabilities().texture_storage_image) {
return;
}
std::vector<gfx::BufferUsageAndFormat> supported_formats =
CreateBufferUsageAndFormatExceptionList();
if (supported_formats.empty()) {
return;
}
// Find a supported_format with a matching resource_format.
bool found = false;
gfx::BufferUsageAndFormat supported_format = supported_formats[0];
viz::ResourceFormat resource_format = static_cast<viz::ResourceFormat>(0);
for (size_t i = 0; !found && i < supported_formats.size(); ++i) {
supported_format = supported_formats[i];
for (size_t j = 0; !found && j <= viz::RESOURCE_FORMAT_MAX; ++j) {
resource_format = static_cast<viz::ResourceFormat>(j);
if (supported_format.format == viz::BufferFormat(resource_format)) {
found = true;
}
}
}
if (!found) {
return;
}
// Create a buffer backed texture and allocate storage.
GLuint texture_id = ri_->CreateTexture(
/*use_buffer=*/true, supported_format.usage, resource_format);
ri_->TexStorage2D(texture_id, 1, kBufferSize.width(), kBufferSize.height());
EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), ri_->GetError());
}
INSTANTIATE_TEST_CASE_P(P, RasterInProcessCommandBufferTest, ::testing::Bool());
} // namespace gpu
......@@ -113,4 +113,21 @@ bool GetImageNeedsPlatformSpecificTextureTarget(gfx::BufferFormat format,
#endif
}
std::vector<gfx::BufferUsageAndFormat>
CreateBufferUsageAndFormatExceptionList() {
std::vector<gfx::BufferUsageAndFormat> usage_format_list;
for (int usage_idx = 0; usage_idx <= static_cast<int>(gfx::BufferUsage::LAST);
++usage_idx) {
gfx::BufferUsage usage = static_cast<gfx::BufferUsage>(usage_idx);
for (int format_idx = 0;
format_idx <= static_cast<int>(gfx::BufferFormat::LAST);
++format_idx) {
gfx::BufferFormat format = static_cast<gfx::BufferFormat>(format_idx);
if (gpu::GetImageNeedsPlatformSpecificTextureTarget(format, usage))
usage_format_list.push_back(gfx::BufferUsageAndFormat(usage, format));
}
}
return usage_format_list;
}
} // namespace gpu
......@@ -5,6 +5,9 @@
#ifndef GPU_IPC_HOST_GPU_MEMORY_BUFFER_SUPPORT_H_
#define GPU_IPC_HOST_GPU_MEMORY_BUFFER_SUPPORT_H_
#include <utility>
#include <vector>
#include "base/containers/hash_tables.h"
#include "base/hash.h"
#include "ui/gfx/buffer_types.h"
......@@ -45,6 +48,11 @@ GpuMemoryBufferConfigurationSet GetNativeGpuMemoryBufferConfigurations(
bool GetImageNeedsPlatformSpecificTextureTarget(gfx::BufferFormat format,
gfx::BufferUsage usage);
// Populate a list of buffer usage/format for which a per platform specific
// texture target must be used instead of GL_TEXTURE_2D.
std::vector<gfx::BufferUsageAndFormat>
CreateBufferUsageAndFormatExceptionList();
} // namespace gpu
#endif // GPU_IPC_HOST_GPU_MEMORY_BUFFER_SUPPORT_H_
......@@ -50,6 +50,7 @@
#include "gpu/config/gpu_crash_keys.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/ipc/gpu_in_process_thread_service.h"
#include "gpu/ipc/host/gpu_memory_buffer_support.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "ui/gfx/geometry/size.h"
......@@ -105,9 +106,12 @@ class GpuInProcessThreadHolder : public base::Thread {
DCHECK(base::CommandLine::InitializedForCurrentProcess());
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
GpuPreferences gpu_preferences = gles2::ParseGpuPreferences(command_line);
gpu_preferences.texture_target_exception_list =
CreateBufferUsageAndFormatExceptionList();
gpu_thread_service_ = base::MakeRefCounted<GpuInProcessThreadService>(
task_runner(), sync_point_manager_.get(), nullptr, nullptr,
gpu_feature_info_, gles2::ParseGpuPreferences(command_line));
gpu_feature_info_, gpu_preferences);
}
return gpu_thread_service_;
}
......@@ -323,7 +327,7 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread(
service_->shader_translator_cache(),
service_->framebuffer_completeness_cache(), feature_info,
params.attribs.bind_generates_resource, service_->image_manager(),
nullptr /* image_factory */, nullptr /* progress_reporter */,
params.image_factory, nullptr /* progress_reporter */,
service_->gpu_feature_info(), service_->discardable_manager());
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment