blob: c63067d8988fb0bc64dfea1a77fd59c8b4b71836 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/command_buffer/service/shared_image_factory.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/command_buffer/tests/texture_image_factory.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_preferences.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/color_space.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/init/gl_factory.h"
namespace gpu {
namespace {
class SharedImageFactoryTest : public testing::TestWithParam<bool> {
public:
void SetUp() override {
surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
ASSERT_TRUE(surface_);
context_ = gl::init::CreateGLContext(nullptr, surface_.get(),
gl::GLContextAttribs());
ASSERT_TRUE(context_);
bool result = context_->MakeCurrent(surface_.get());
ASSERT_TRUE(result);
GpuPreferences preferences;
preferences.use_passthrough_cmd_decoder = use_passthrough();
GpuDriverBugWorkarounds workarounds;
workarounds.max_texture_size = INT_MAX - 1;
factory_ = std::make_unique<SharedImageFactory>(
preferences, workarounds, GpuFeatureInfo(), &mailbox_manager_,
&image_factory_, nullptr);
}
void TearDown() override {
factory_->DestroyAllSharedImages(true);
factory_.reset();
}
bool use_passthrough() {
return GetParam() && gles2::PassthroughCommandDecoderSupported();
}
protected:
scoped_refptr<gl::GLSurface> surface_;
scoped_refptr<gl::GLContext> context_;
gles2::MailboxManagerImpl mailbox_manager_;
TextureImageFactory image_factory_;
std::unique_ptr<SharedImageFactory> factory_;
};
TEST_P(SharedImageFactoryTest, Basic) {
auto mailbox = Mailbox::Generate();
auto format = viz::ResourceFormat::RGBA_8888;
gfx::Size size(256, 256);
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
EXPECT_TRUE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
TextureBase* texture_base = mailbox_manager_.ConsumeTexture(mailbox);
ASSERT_TRUE(texture_base);
GLenum expected_target = GL_TEXTURE_2D;
EXPECT_EQ(texture_base->target(), expected_target);
if (!use_passthrough()) {
auto* texture = static_cast<gles2::Texture*>(texture_base);
EXPECT_TRUE(texture->IsImmutable());
int width, height, depth;
bool has_level =
texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height, &depth);
EXPECT_TRUE(has_level);
EXPECT_EQ(width, size.width());
EXPECT_EQ(height, size.height());
}
EXPECT_TRUE(factory_->DestroySharedImage(mailbox));
EXPECT_FALSE(mailbox_manager_.ConsumeTexture(mailbox));
}
TEST_P(SharedImageFactoryTest, Image) {
auto mailbox = Mailbox::Generate();
auto format = viz::ResourceFormat::RGBA_8888;
gfx::Size size(256, 256);
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_SCANOUT;
EXPECT_TRUE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
TextureBase* texture_base = mailbox_manager_.ConsumeTexture(mailbox);
ASSERT_TRUE(texture_base);
GLenum target = texture_base->target();
scoped_refptr<gl::GLImage> image;
if (use_passthrough()) {
auto* texture = static_cast<gles2::TexturePassthrough*>(texture_base);
image = texture->GetLevelImage(target, 0);
} else {
auto* texture = static_cast<gles2::Texture*>(texture_base);
image = texture->GetLevelImage(target, 0);
}
ASSERT_TRUE(image);
EXPECT_EQ(size, image->GetSize());
}
TEST_P(SharedImageFactoryTest, DuplicateMailbox) {
auto mailbox = Mailbox::Generate();
auto format = viz::ResourceFormat::RGBA_8888;
gfx::Size size(256, 256);
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
EXPECT_TRUE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
EXPECT_FALSE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
}
TEST_P(SharedImageFactoryTest, DestroyInexistentMailbox) {
auto mailbox = Mailbox::Generate();
EXPECT_FALSE(factory_->DestroySharedImage(mailbox));
}
TEST_P(SharedImageFactoryTest, InvalidFormat) {
auto mailbox = Mailbox::Generate();
auto format = viz::ResourceFormat::UYVY_422;
gfx::Size size(256, 256);
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
EXPECT_FALSE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
}
TEST_P(SharedImageFactoryTest, InvalidSize) {
auto mailbox = Mailbox::Generate();
auto format = viz::ResourceFormat::RGBA_8888;
gfx::Size size(0, 0);
auto color_space = gfx::ColorSpace::CreateSRGB();
uint32_t usage = SHARED_IMAGE_USAGE_GLES2;
EXPECT_FALSE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
size = gfx::Size(INT_MAX, INT_MAX);
EXPECT_FALSE(
factory_->CreateSharedImage(mailbox, format, size, color_space, usage));
}
INSTANTIATE_TEST_CASE_P(Service, SharedImageFactoryTest, ::testing::Bool());
} // anonymous namespace
} // namespace gpu