blob: 78a4924cbe45878b5676cfeab6ec060b620ac981 [file] [log] [blame]
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DisplayVkAndroid.cpp:
// Implements the class methods for DisplayVkAndroid.
//
#include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
#include <android/log.h>
#include <android/native_window.h>
#include <vulkan/vulkan.h>
#include "common/angle_version.h"
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.h"
#include "libANGLE/renderer/vulkan/android/WindowSurfaceVkAndroid.h"
#include "libANGLE/renderer/vulkan/vk_caps_utils.h"
namespace rx
{
DisplayVkAndroid::DisplayVkAndroid(const egl::DisplayState &state) : DisplayVk(state) {}
egl::Error DisplayVkAndroid::initialize(egl::Display *display)
{
ANGLE_TRY(DisplayVk::initialize(display));
std::stringstream strstr;
strstr << "Version (" << ANGLE_VERSION_STRING << "), ";
strstr << "Renderer (" << mRenderer->getRendererDescription() << ")";
__android_log_print(ANDROID_LOG_INFO, "ANGLE", "%s", strstr.str().c_str());
return egl::NoError();
}
bool DisplayVkAndroid::isValidNativeWindow(EGLNativeWindowType window) const
{
return (ANativeWindow_getFormat(window) >= 0);
}
SurfaceImpl *DisplayVkAndroid::createWindowSurfaceVk(const egl::SurfaceState &state,
EGLNativeWindowType window)
{
return new WindowSurfaceVkAndroid(state, window);
}
egl::ConfigSet DisplayVkAndroid::generateConfigs()
{
// TODO (Issue 4062): Add conditional support for GL_RGB10_A2 and GL_RGBA16F when the
// Android Vulkan loader adds conditional support for them.
const std::array<GLenum, 3> kColorFormats = {GL_RGBA8, GL_RGB8, GL_RGB565};
std::vector<GLenum> depthStencilFormats(
egl_vk::kConfigDepthStencilFormats,
egl_vk::kConfigDepthStencilFormats + ArraySize(egl_vk::kConfigDepthStencilFormats));
if (getCaps().stencil8)
{
depthStencilFormats.push_back(GL_STENCIL_INDEX8);
}
return egl_vk::GenerateConfigs(kColorFormats.data(), kColorFormats.size(),
depthStencilFormats.data(), depthStencilFormats.size(), this);
}
void DisplayVkAndroid::enableRecordableIfSupported(egl::Config *config)
{
const VkPhysicalDeviceProperties &physicalDeviceProperties =
getRenderer()->getPhysicalDeviceProperties();
// TODO(b/181163023): Determine how to properly query for support. This is a hack to unblock
// launching SwANGLE on Cuttlefish.
bool isSwiftShader =
IsSwiftshader(physicalDeviceProperties.vendorID, physicalDeviceProperties.deviceID);
if (isSwiftShader)
{
config->recordable = true;
}
}
void DisplayVkAndroid::checkConfigSupport(egl::Config *config)
{
// TODO(geofflang): Test for native support and modify the config accordingly.
// anglebug.com/2692
enableRecordableIfSupported(config);
}
egl::Error DisplayVkAndroid::validateImageClientBuffer(const gl::Context *context,
EGLenum target,
EGLClientBuffer clientBuffer,
const egl::AttributeMap &attribs) const
{
switch (target)
{
case EGL_NATIVE_BUFFER_ANDROID:
return HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(mRenderer,
clientBuffer);
default:
return DisplayVk::validateImageClientBuffer(context, target, clientBuffer, attribs);
}
}
ExternalImageSiblingImpl *DisplayVkAndroid::createExternalImageSibling(
const gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
switch (target)
{
case EGL_NATIVE_BUFFER_ANDROID:
return new HardwareBufferImageSiblingVkAndroid(buffer);
default:
return DisplayVk::createExternalImageSibling(context, target, buffer, attribs);
}
}
const char *DisplayVkAndroid::getWSIExtension() const
{
return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
}
bool IsVulkanAndroidDisplayAvailable()
{
return true;
}
DisplayImpl *CreateVulkanAndroidDisplay(const egl::DisplayState &state)
{
return new DisplayVkAndroid(state);
}
} // namespace rx