blob: 9e9c0e9716a393686624b676e88d7f5a5f8e2492 [file]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <memory>
#include "base/memory/raw_ptr.h"
#include "base/strings/stringize_macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/client_native_pixmap.h"
#include "ui/gfx/color_space.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_display.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/init/gl_factory.h"
#include "ui/gl/test/gl_test_support.h"
#include "ui/ozone/public/client_native_pixmap_factory_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/surface_factory_ozone.h"
// TODO(crbug.com/40630408): Fix memory leaks in tests and re-enable on LSAN.
#ifdef LEAK_SANITIZER
#define MAYBE_Create DISABLED_Create
#else
#define MAYBE_Create Create
#endif
namespace gl {
namespace {
constexpr gfx::BufferUsage kUsage = gfx::BufferUsage::SCANOUT;
constexpr viz::SharedImageFormat kFormat = viz::SinglePlaneFormat::kBGRA_8888;
bool SkipTest() {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
ui::GLOzone* gl_ozone = ui::OzonePlatform::GetInstance()
->GetSurfaceFactoryOzone()
->GetCurrentGLOzone();
if (!gl_ozone || !gl_ozone->CanImportNativePixmap(kFormat)) {
LOG(WARNING) << "Skip test, ozone implementation can't import native "
<< "pixmaps";
return true;
}
return false;
}
class NativePixmapGLBindingTest : public testing::Test {
public:
NativePixmapGLBindingTest() {
client_native_pixmap_factory_ = ui::CreateClientNativePixmapFactoryOzone();
}
protected:
// Overridden from testing::Test:
void SetUp() override {
if (SkipTest()) {
GTEST_SKIP();
}
display_ = GLTestSupport::InitializeGL(std::nullopt);
surface_ = gl::init::CreateOffscreenGLSurface(display_, gfx::Size());
context_ =
gl::init::CreateGLContext(nullptr, surface_.get(), GLContextAttribs());
context_->MakeCurrent(surface_.get());
}
void TearDown() override {
if (texture_id_) {
glDeleteTextures(1, &texture_id_);
}
if (context_) {
context_->ReleaseCurrent(surface_.get());
context_ = nullptr;
}
surface_ = nullptr;
GLTestSupport::CleanupGL(display_);
}
protected:
std::unique_ptr<ui::NativePixmapGLBinding> CreateSolidColorImage(
const gfx::Size& size) {
ui::SurfaceFactoryOzone* surface_factory =
ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone();
scoped_refptr<gfx::NativePixmap> pixmap =
surface_factory->CreateNativePixmap(gfx::kNullAcceleratedWidget,
nullptr, size, kFormat, kUsage);
DCHECK(pixmap) << "Offending format: " << kFormat.ToString();
// Create a dummy texture ID to bind - these tests don't actually care about
// binding.
if (!texture_id_) {
glGenTextures(1, &texture_id_);
}
ui::GLOzone* gl_ozone = ui::OzonePlatform::GetInstance()
->GetSurfaceFactoryOzone()
->GetCurrentGLOzone();
EXPECT_TRUE(gl_ozone->CanImportNativePixmap(kFormat));
// The imported pixmap can be externally sampled i.e. does not provide
// per-plane textures but provides a unified single texture object.
auto binding = gl_ozone->ImportNativePixmap(
std::move(pixmap), kFormat, /*plane_index=*/std::nullopt, size,
gfx::ColorSpace(), GL_TEXTURE_EXTERNAL_OES, texture_id_);
EXPECT_TRUE(binding);
return binding;
}
scoped_refptr<GLSurface> surface_;
scoped_refptr<GLContext> context_;
GLuint texture_id_ = 0;
std::unique_ptr<gfx::ClientNativePixmapFactory> client_native_pixmap_factory_;
raw_ptr<GLDisplay> display_ = nullptr;
};
TEST_F(NativePixmapGLBindingTest, MAYBE_Create) {
// NOTE: On some drm devices (mediatek) the minimum width/height to add an fb
// for a bo must be 64, and YVU_420 in i915 requires at least 128 length.
const gfx::Size small_image_size(128, 128);
const gfx::Size large_image_size(512, 512);
// Create a small solid color green image of preferred format.
auto small_image = CreateSolidColorImage(small_image_size);
ASSERT_TRUE(small_image);
// Create a large solid color green image of preferred format.
auto large_image = CreateSolidColorImage(large_image_size);
ASSERT_TRUE(large_image);
}
} // namespace
} // namespace gl