Commit 62120966 authored by Ashitha Santhosh's avatar Ashitha Santhosh Committed by Commit Bot

Testing for SwapChainFactoryDXGI

Updated GLImageDXGISwapChain to use EGL Images instead
of pbuffer surfaces, to avoid creating render target view
for front buffer.

Bug: 939655
Change-Id: Iec80f399724ee0509dd95d126c0d3dbb883bb87c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1663014Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Commit-Queue: Ashitha Santhosh <ashithasantosh@google.com>
Cr-Commit-Position: refs/heads/master@{#671369}
parent 3d60a8b1
......@@ -392,6 +392,7 @@ test("gl_tests") {
"//ui/platform_window",
"//ui/platform_window:platform_impls",
]
sources += [ "command_buffer/service/swap_chain_factory_dxgi_unittest.cc" ]
}
if (use_dawn) {
......
......@@ -229,15 +229,15 @@ class SharedImageBackingDXGISwapChain : public SharedImageBacking {
gl::GLImage* image;
unsigned target = GL_TEXTURE_2D;
gles2::Texture::ImageState image_state;
if (texture_) {
gles2::Texture::ImageState image_state;
image = texture_->GetLevelImage(target, 0, &image_state);
DCHECK_EQ(image_state, gles2::Texture::BOUND);
} else {
DCHECK(texture_passthrough_);
image = texture_passthrough_->GetLevelImage(target, 0);
}
DCHECK(image);
DCHECK_EQ(image_state, gles2::Texture::BOUND);
if (!image->BindTexImage(target)) {
DLOG(ERROR) << "Failed to rebind texture to new surface.";
......@@ -314,6 +314,10 @@ std::unique_ptr<SharedImageBacking> SwapChainFactoryDXGI::MakeBacking(
auto image = base::MakeRefCounted<gl::GLImageDXGISwapChain>(
size, viz::BufferFormat(format), d3d11_texture, swap_chain);
if (!image->Initialize()) {
DLOG(ERROR) << "Failed to create EGL image";
return nullptr;
}
if (!image->BindTexImage(target)) {
DLOG(ERROR) << "Failed to bind image to swap chain D3D11 texture.";
return nullptr;
......@@ -393,7 +397,7 @@ SwapChainFactoryDXGI::SwapChainBackings SwapChainFactoryDXGI::CreateSwapChain(
desc.Stereo = FALSE;
desc.SampleDesc.Count = 1;
desc.BufferCount = 2;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
desc.Flags = 0;
......
......@@ -28,7 +28,7 @@ class GPU_GLES2_EXPORT SwapChainFactoryDXGI {
explicit SwapChainFactoryDXGI(bool use_passthrough);
~SwapChainFactoryDXGI();
struct SwapChainBackings {
struct GPU_GLES2_EXPORT SwapChainBackings {
SwapChainBackings(std::unique_ptr<SharedImageBacking> front_buffer,
std::unique_ptr<SharedImageBacking> back_buffer);
~SwapChainBackings();
......
This diff is collapsed.
......@@ -7,28 +7,15 @@
#include "ui/gl/egl_util.h"
#include "ui/gl/gl_bindings.h"
#ifndef EGL_ANGLE_d3d_texture_client_buffer
#define EGL_ANGLE_d3d_texture_client_buffer 1
#define EGL_D3D_TEXTURE_ANGLE 0x33A3
#endif /* EGL_ANGLE_d3d_texture_client_buffer */
#ifndef EGL_ANGLE_image_d3d11_texture
#define EGL_D3D11_TEXTURE_ANGLE 0x3484
#endif /* EGL_ANGLE_image_d3d11_texture */
namespace gl {
namespace {
bool SwapChainSupportedBindFormat(gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::RGBX_8888:
case gfx::BufferFormat::RGBA_F16:
return true;
default:
return false;
};
}
bool SwapChainHasAlpha(gfx::BufferFormat format) {
DCHECK(SwapChainSupportedBindFormat(format));
switch (format) {
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::RGBA_F16:
......@@ -41,94 +28,6 @@ bool SwapChainHasAlpha(gfx::BufferFormat format) {
};
}
EGLConfig ChooseCompatibleConfig(gfx::BufferFormat format, EGLDisplay display) {
DCHECK(SwapChainSupportedBindFormat(format));
const EGLint color_bits = format == gfx::BufferFormat::RGBA_F16 ? 16 : 8;
const EGLint buffer_bind_to_texture = SwapChainHasAlpha(format)
? EGL_BIND_TO_TEXTURE_RGBA
: EGL_BIND_TO_TEXTURE_RGB;
const EGLint buffer_size =
color_bits * 3 + (SwapChainHasAlpha(format) ? color_bits : 0);
std::vector<EGLint> attrib_list = {
EGL_RED_SIZE, color_bits, EGL_GREEN_SIZE, color_bits,
EGL_BLUE_SIZE, color_bits, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
buffer_bind_to_texture, EGL_TRUE, EGL_BUFFER_SIZE, buffer_size};
// It is assumed that EGL_EXT_pixel_format_float extension is supported by
// ANGLE.
if (format == gfx::BufferFormat::RGBA_F16) {
attrib_list.push_back(EGL_COLOR_COMPONENT_TYPE_EXT);
attrib_list.push_back(EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT);
}
attrib_list.push_back(EGL_NONE);
EGLint num_config = 0;
EGLBoolean result =
eglChooseConfig(display, attrib_list.data(), nullptr, 0, &num_config);
if (result != EGL_TRUE)
return nullptr;
std::vector<EGLConfig> all_configs(num_config);
result = eglChooseConfig(display, attrib_list.data(), all_configs.data(),
num_config, &num_config);
if (result != EGL_TRUE)
return nullptr;
for (EGLConfig config : all_configs) {
EGLint bits = 0;
// Ensures that the config chosen has requested number of bits.
if (!eglGetConfigAttrib(display, config, EGL_RED_SIZE, &bits) ||
bits != color_bits) {
continue;
}
if (!eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &bits) ||
bits != color_bits) {
continue;
}
if (!eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &bits) ||
bits != color_bits) {
continue;
}
if (SwapChainHasAlpha(format) &&
(!eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &bits) ||
bits != color_bits)) {
continue;
}
return config;
}
return nullptr;
}
EGLSurface CreatePbuffer(const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture,
gfx::BufferFormat format,
EGLConfig config,
EGLDisplay display,
unsigned target) {
DCHECK(SwapChainSupportedBindFormat(format));
D3D11_TEXTURE2D_DESC desc;
texture->GetDesc(&desc);
EGLint width = desc.Width;
EGLint height = desc.Height;
EGLint pBufferAttributes[] = {
EGL_WIDTH,
width,
EGL_HEIGHT,
height,
EGL_TEXTURE_TARGET,
EGL_TEXTURE_2D,
EGL_TEXTURE_FORMAT,
SwapChainHasAlpha(format) ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
EGL_NONE};
return eglCreatePbufferFromClientBuffer(
display, EGL_D3D_TEXTURE_ANGLE, texture.Get(), config, pBufferAttributes);
}
} // anonymous namespace
GLImageDXGISwapChain::GLImageDXGISwapChain(
......@@ -136,38 +35,29 @@ GLImageDXGISwapChain::GLImageDXGISwapChain(
gfx::BufferFormat buffer_format,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain)
: size_(size),
: GLImageEGL(size),
buffer_format_(buffer_format),
texture_(texture),
swap_chain_(swap_chain),
display_(eglGetCurrentDisplay()),
config_(ChooseCompatibleConfig(buffer_format, display_)) {
swap_chain_(swap_chain) {
DCHECK(texture_);
DCHECK(swap_chain_);
DCHECK(config_);
}
GLImage::BindOrCopy GLImageDXGISwapChain::ShouldBindOrCopy() {
return BIND;
// static
GLImageDXGISwapChain* GLImageDXGISwapChain::FromGLImage(GLImage* image) {
if (!image || image->GetType() != Type::DXGI_SWAP_CHAIN)
return nullptr;
return static_cast<GLImageDXGISwapChain*>(image);
}
bool GLImageDXGISwapChain::BindTexImage(unsigned target) {
DestroySurface();
bool GLImageDXGISwapChain::Initialize() {
DCHECK(texture_);
DCHECK_EQ(surface_, EGL_NO_SURFACE);
DCHECK(config_);
surface_ = CreatePbuffer(texture_, buffer_format_, config_, display_, target);
if (surface_ == EGL_NO_SURFACE) {
DLOG(ERROR) << "eglCreatePbufferSurface failed with error "
<< ui::GetLastEGLErrorString();
return false;
}
return eglBindTexImage(display_, surface_, EGL_BACK_BUFFER) == EGL_TRUE;
const EGLint attribs[] = {EGL_NONE};
return GLImageEGL::Initialize(EGL_NO_CONTEXT, EGL_D3D11_TEXTURE_ANGLE,
static_cast<EGLClientBuffer>(texture_.Get()),
attribs);
}
void GLImageDXGISwapChain::ReleaseTexImage(unsigned target) {}
bool GLImageDXGISwapChain::CopyTexImage(unsigned target) {
return false;
}
......@@ -184,10 +74,6 @@ unsigned GLImageDXGISwapChain::GetInternalFormat() {
return SwapChainHasAlpha(buffer_format_) ? GL_RGBA : GL_RGB;
}
gfx::Size GLImageDXGISwapChain::GetSize() {
return size_;
}
void GLImageDXGISwapChain::OnMemoryDump(
base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......@@ -209,18 +95,6 @@ bool GLImageDXGISwapChain::ScheduleOverlayPlane(
return false;
}
void GLImageDXGISwapChain::DestroySurface() {
if (surface_ != EGL_NO_SURFACE) {
if (!eglDestroySurface(display_, surface_)) {
DLOG(ERROR) << "eglDestroySurface failed with error "
<< ui::GetLastEGLErrorString();
}
surface_ = EGL_NO_SURFACE;
}
}
GLImageDXGISwapChain::~GLImageDXGISwapChain() {
DestroySurface();
}
GLImageDXGISwapChain::~GLImageDXGISwapChain() {}
} // namespace gl
......@@ -11,31 +11,30 @@
#include <wrl/client.h>
#include "ui/gfx/buffer_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_image_egl.h"
namespace gl {
class GL_EXPORT GLImageDXGISwapChain : public gl::GLImage {
class GL_EXPORT GLImageDXGISwapChain : public gl::GLImageEGL {
public:
GLImageDXGISwapChain(const gfx::Size& size,
gfx::BufferFormat buffer_format,
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture,
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain);
// Safe downcast. Returns nullptr on failure.
static GLImageDXGISwapChain* FromGLImage(GLImage* image);
bool Initialize();
// GLImage implementation
BindOrCopy ShouldBindOrCopy() override;
// Destroys surface(if present), and binds image to new pixel buffer surface.
bool BindTexImage(unsigned target) override;
void ReleaseTexImage(unsigned target) override;
bool CopyTexImage(unsigned target) override;
bool CopyTexSubImage(unsigned target,
const gfx::Point& offset,
const gfx::Rect& rect) override;
void Flush() override;
unsigned GetInternalFormat() override;
gfx::Size GetSize() override;
Type GetType() const override;
void OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t process_tracing_id,
......@@ -48,22 +47,19 @@ class GL_EXPORT GLImageDXGISwapChain : public gl::GLImage {
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) override;
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture() { return texture_; }
const Microsoft::WRL::ComPtr<ID3D11Texture2D>& texture() { return texture_; }
const Microsoft::WRL::ComPtr<IDXGISwapChain1>& swap_chain() {
return swap_chain_;
}
protected:
~GLImageDXGISwapChain() override;
private:
void DestroySurface();
const gfx::Size size_;
const gfx::BufferFormat buffer_format_;
EGLSurface surface_ = nullptr;
Microsoft::WRL::ComPtr<ID3D11Texture2D> texture_;
// Required by Direct composition surface to pass swap chain handle to OS.
Microsoft::WRL::ComPtr<IDXGISwapChain1> swap_chain_;
const EGLDisplay display_;
const EGLConfig config_;
DISALLOW_COPY_AND_ASSIGN(GLImageDXGISwapChain);
};
......
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