Merge changes from topics "GL_screen_decor", "VK_screen_decor"
* changes: Plumb support for rendering A8 in Vulkan Plumb through A8 for GL/EGL Add COLOR_MODE_A8/ColorMode::A8 Treat AHARDWAREBUFFER_FORMAT_R8_UNORM as kAlpha_8_SkAlphaType
This commit is contained in:
committed by
Android (Google) Code Review
commit
f96aa9e82b
@@ -304,12 +304,23 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
* @see android.R.attr#colorMode
|
||||
*/
|
||||
public static final int COLOR_MODE_HDR = 2;
|
||||
// 3 Corresponds to android::uirenderer::ColorMode::Hdr10.
|
||||
/**
|
||||
* Value of {@link #colorMode} indicating that the activity should use an
|
||||
* 8 bit alpha buffer if the presentation display supports it.
|
||||
*
|
||||
* @see android.R.attr#colorMode
|
||||
* @hide
|
||||
*/
|
||||
public static final int COLOR_MODE_A8 = 4;
|
||||
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "COLOR_MODE_" }, value = {
|
||||
COLOR_MODE_DEFAULT,
|
||||
COLOR_MODE_WIDE_COLOR_GAMUT,
|
||||
COLOR_MODE_HDR,
|
||||
COLOR_MODE_A8,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ColorMode {}
|
||||
@@ -1682,6 +1693,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
return "COLOR_MODE_WIDE_COLOR_GAMUT";
|
||||
case COLOR_MODE_HDR:
|
||||
return "COLOR_MODE_HDR";
|
||||
case COLOR_MODE_A8:
|
||||
return "COLOR_MODE_A8";
|
||||
default:
|
||||
return Integer.toString(colorMode);
|
||||
}
|
||||
|
||||
@@ -4910,13 +4910,14 @@ public final class ViewRootImpl implements ViewParent,
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColorModeIfNeeded(int colorMode) {
|
||||
private void updateColorModeIfNeeded(@ActivityInfo.ColorMode int colorMode) {
|
||||
if (mAttachInfo.mThreadedRenderer == null) {
|
||||
return;
|
||||
}
|
||||
// TODO: Centralize this sanitization? Why do we let setting bad modes?
|
||||
// Alternatively, can we just let HWUI figure it out? Do we need to care here?
|
||||
if (!getConfiguration().isScreenWideColorGamut()) {
|
||||
if (colorMode != ActivityInfo.COLOR_MODE_A8
|
||||
&& !getConfiguration().isScreenWideColorGamut()) {
|
||||
colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
|
||||
}
|
||||
mAttachInfo.mThreadedRenderer.setColorMode(colorMode);
|
||||
|
||||
@@ -29,6 +29,8 @@ enum class ColorMode {
|
||||
Hdr = 2,
|
||||
// HDR Rec2020 + 1010102
|
||||
Hdr10 = 3,
|
||||
// Alpha 8
|
||||
A8 = 4,
|
||||
};
|
||||
|
||||
} // namespace android::uirenderer
|
||||
|
||||
@@ -91,6 +91,8 @@ bool SkiaOpenGLPipeline::draw(const Frame& frame, const SkRect& screenDirty, con
|
||||
fboInfo.fFormat = GL_RGBA8;
|
||||
} else if (colorType == kRGBA_1010102_SkColorType) {
|
||||
fboInfo.fFormat = GL_RGB10_A2;
|
||||
} else if (colorType == kAlpha_8_SkColorType) {
|
||||
fboInfo.fFormat = GL_R8;
|
||||
} else {
|
||||
LOG_ALWAYS_FATAL("Unsupported color type.");
|
||||
}
|
||||
|
||||
@@ -613,6 +613,10 @@ void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) {
|
||||
mSurfaceColorType = SkColorType::kRGBA_1010102_SkColorType;
|
||||
mSurfaceColorSpace = SkColorSpace::MakeRGB(GetPQSkTransferFunction(), SkNamedGamut::kRec2020);
|
||||
break;
|
||||
case ColorMode::A8:
|
||||
mSurfaceColorType = SkColorType::kAlpha_8_SkColorType;
|
||||
mSurfaceColorSpace = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ EglManager::EglManager()
|
||||
, mEglConfig(nullptr)
|
||||
, mEglConfigF16(nullptr)
|
||||
, mEglConfig1010102(nullptr)
|
||||
, mEglConfigA8(nullptr)
|
||||
, mEglContext(EGL_NO_CONTEXT)
|
||||
, mPBufferSurface(EGL_NO_SURFACE)
|
||||
, mCurrentSurface(EGL_NO_SURFACE)
|
||||
@@ -246,6 +247,52 @@ EGLConfig EglManager::loadFP16Config(EGLDisplay display, SwapBehavior swapBehavi
|
||||
return config;
|
||||
}
|
||||
|
||||
EGLConfig EglManager::loadA8Config(EGLDisplay display, EglManager::SwapBehavior swapBehavior) {
|
||||
EGLint eglSwapBehavior =
|
||||
(swapBehavior == SwapBehavior::Preserved) ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
|
||||
EGLint attribs[] = {EGL_RENDERABLE_TYPE,
|
||||
EGL_OPENGL_ES2_BIT,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
0,
|
||||
EGL_BLUE_SIZE,
|
||||
0,
|
||||
EGL_ALPHA_SIZE,
|
||||
0,
|
||||
EGL_DEPTH_SIZE,
|
||||
0,
|
||||
EGL_STENCIL_SIZE,
|
||||
STENCIL_BUFFER_SIZE,
|
||||
EGL_SURFACE_TYPE,
|
||||
EGL_WINDOW_BIT | eglSwapBehavior,
|
||||
EGL_NONE};
|
||||
EGLint numConfigs = 1;
|
||||
if (!eglChooseConfig(display, attribs, nullptr, numConfigs, &numConfigs)) {
|
||||
return EGL_NO_CONFIG_KHR;
|
||||
}
|
||||
|
||||
std::vector<EGLConfig> configs(numConfigs, EGL_NO_CONFIG_KHR);
|
||||
if (!eglChooseConfig(display, attribs, configs.data(), numConfigs, &numConfigs)) {
|
||||
return EGL_NO_CONFIG_KHR;
|
||||
}
|
||||
|
||||
// The component sizes passed to eglChooseConfig are minimums, so configs
|
||||
// contains entries that exceed them. Choose one that matches the sizes
|
||||
// exactly.
|
||||
for (EGLConfig config : configs) {
|
||||
EGLint r{0}, g{0}, b{0}, a{0};
|
||||
eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r);
|
||||
eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
|
||||
eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b);
|
||||
eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
|
||||
if (8 == r && 0 == g && 0 == b && 0 == a) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return EGL_NO_CONFIG_KHR;
|
||||
}
|
||||
|
||||
void EglManager::initExtensions() {
|
||||
auto extensions = StringUtils::split(eglQueryString(mEglDisplay, EGL_EXTENSIONS));
|
||||
|
||||
@@ -307,6 +354,10 @@ void EglManager::loadConfigs() {
|
||||
ALOGW("Failed to initialize 101010-2 format, error = %s",
|
||||
eglErrorString());
|
||||
}
|
||||
mEglConfigA8 = loadA8Config(mEglDisplay, mSwapBehavior);
|
||||
if (mEglConfigA8 == EGL_NO_CONFIG_KHR) {
|
||||
ALOGE("Failed to initialize A8 format, error = %s", eglErrorString());
|
||||
}
|
||||
}
|
||||
|
||||
void EglManager::createContext() {
|
||||
@@ -345,10 +396,14 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
|
||||
sk_sp<SkColorSpace> colorSpace) {
|
||||
LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
|
||||
|
||||
if (!mHasWideColorGamutSupport || !EglExtensions.noConfigContext) {
|
||||
if (!EglExtensions.noConfigContext) {
|
||||
// The caller shouldn't use A8 if we cannot switch modes.
|
||||
LOG_ALWAYS_FATAL_IF(colorMode == ColorMode::A8,
|
||||
"Cannot use A8 without EGL_KHR_no_config_context!");
|
||||
|
||||
// Cannot switch modes without EGL_KHR_no_config_context.
|
||||
colorMode = ColorMode::Default;
|
||||
}
|
||||
|
||||
// The color space we want to use depends on whether linear blending is turned
|
||||
// on and whether the app has requested wide color gamut rendering. When wide
|
||||
// color gamut rendering is off, the app simply renders in the display's native
|
||||
@@ -374,42 +429,57 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,
|
||||
EGLint attribs[] = {EGL_NONE, EGL_NONE, EGL_NONE};
|
||||
|
||||
EGLConfig config = mEglConfig;
|
||||
if (DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType) {
|
||||
if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
|
||||
if (colorMode == ColorMode::A8) {
|
||||
// A8 doesn't use a color space
|
||||
config = mEglConfigA8;
|
||||
|
||||
LOG_ALWAYS_FATAL_IF(!mEglConfigA8, "Requested ColorMode::A8, but EGL lacks support!");
|
||||
} else {
|
||||
if (!mHasWideColorGamutSupport) {
|
||||
colorMode = ColorMode::Default;
|
||||
} else {
|
||||
config = mEglConfigF16;
|
||||
}
|
||||
}
|
||||
if (EglExtensions.glColorSpace) {
|
||||
attribs[0] = EGL_GL_COLORSPACE_KHR;
|
||||
switch (colorMode) {
|
||||
case ColorMode::Default:
|
||||
attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
|
||||
break;
|
||||
case ColorMode::WideColorGamut: {
|
||||
skcms_Matrix3x3 colorGamut;
|
||||
LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
|
||||
"Could not get gamut matrix from color space");
|
||||
if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
|
||||
} else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
|
||||
} else if (memcmp(&colorGamut, &SkNamedGamut::kRec2020, sizeof(colorGamut)) == 0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
} else {
|
||||
LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ColorMode::Hdr:
|
||||
|
||||
if (DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType) {
|
||||
if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
|
||||
colorMode = ColorMode::Default;
|
||||
} else {
|
||||
config = mEglConfigF16;
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
break;
|
||||
case ColorMode::Hdr10:
|
||||
config = mEglConfig1010102;
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (EglExtensions.glColorSpace) {
|
||||
attribs[0] = EGL_GL_COLORSPACE_KHR;
|
||||
switch (colorMode) {
|
||||
case ColorMode::Default:
|
||||
attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
|
||||
break;
|
||||
case ColorMode::WideColorGamut: {
|
||||
skcms_Matrix3x3 colorGamut;
|
||||
LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut),
|
||||
"Could not get gamut matrix from color space");
|
||||
if (memcmp(&colorGamut, &SkNamedGamut::kDisplayP3, sizeof(colorGamut)) == 0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;
|
||||
} else if (memcmp(&colorGamut, &SkNamedGamut::kSRGB, sizeof(colorGamut)) == 0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
|
||||
} else if (memcmp(&colorGamut, &SkNamedGamut::kRec2020, sizeof(colorGamut)) ==
|
||||
0) {
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
} else {
|
||||
LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ColorMode::Hdr:
|
||||
config = mEglConfigF16;
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
break;
|
||||
case ColorMode::Hdr10:
|
||||
config = mEglConfig1010102;
|
||||
attribs[1] = EGL_GL_COLORSPACE_BT2020_PQ_EXT;
|
||||
break;
|
||||
case ColorMode::A8:
|
||||
LOG_ALWAYS_FATAL("Unreachable: A8 doesn't use a color space");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ private:
|
||||
static EGLConfig load8BitsConfig(EGLDisplay display, SwapBehavior swapBehavior);
|
||||
static EGLConfig loadFP16Config(EGLDisplay display, SwapBehavior swapBehavior);
|
||||
static EGLConfig load1010102Config(EGLDisplay display, SwapBehavior swapBehavior);
|
||||
static EGLConfig loadA8Config(EGLDisplay display, SwapBehavior swapBehavior);
|
||||
|
||||
void initExtensions();
|
||||
void createPBufferSurface();
|
||||
@@ -100,6 +101,7 @@ private:
|
||||
EGLConfig mEglConfig;
|
||||
EGLConfig mEglConfigF16;
|
||||
EGLConfig mEglConfig1010102;
|
||||
EGLConfig mEglConfigA8;
|
||||
EGLContext mEglContext;
|
||||
EGLSurface mPBufferSurface;
|
||||
EGLSurface mCurrentSurface;
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include "pipeline/skia/ShaderCache.h"
|
||||
#include "renderstate/RenderState.h"
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "VulkanManager"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
namespace renderthread {
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include "VulkanManager.h"
|
||||
#include "utils/Color.h"
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "VulkanSurface"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
namespace renderthread {
|
||||
@@ -197,8 +200,9 @@ bool VulkanSurface::InitializeWindowInfoStruct(ANativeWindow* window, ColorMode
|
||||
outWindowInfo->bufferFormat = ColorTypeToBufferFormat(colorType);
|
||||
outWindowInfo->colorspace = colorSpace;
|
||||
outWindowInfo->dataspace = ColorSpaceToADataSpace(colorSpace.get(), colorType);
|
||||
LOG_ALWAYS_FATAL_IF(outWindowInfo->dataspace == HAL_DATASPACE_UNKNOWN,
|
||||
"Unsupported colorspace");
|
||||
LOG_ALWAYS_FATAL_IF(
|
||||
outWindowInfo->dataspace == HAL_DATASPACE_UNKNOWN && colorType != kAlpha_8_SkColorType,
|
||||
"Unsupported colorspace");
|
||||
|
||||
VkFormat vkPixelFormat;
|
||||
switch (colorType) {
|
||||
@@ -211,6 +215,9 @@ bool VulkanSurface::InitializeWindowInfoStruct(ANativeWindow* window, ColorMode
|
||||
case kRGBA_1010102_SkColorType:
|
||||
vkPixelFormat = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||
break;
|
||||
case kAlpha_8_SkColorType:
|
||||
vkPixelFormat = VK_FORMAT_R8_UNORM;
|
||||
break;
|
||||
default:
|
||||
LOG_ALWAYS_FATAL("Unsupported colorType: %d", (int)colorType);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ static inline SkImageInfo createImageInfo(int32_t width, int32_t height, int32_t
|
||||
colorType = kRGBA_F16_SkColorType;
|
||||
alphaType = kPremul_SkAlphaType;
|
||||
break;
|
||||
case AHARDWAREBUFFER_FORMAT_R8_UNORM:
|
||||
colorType = kAlpha_8_SkColorType;
|
||||
alphaType = kPremul_SkAlphaType;
|
||||
break;
|
||||
default:
|
||||
ALOGV("Unsupported format: %d, return unknown by default", format);
|
||||
break;
|
||||
@@ -90,6 +94,8 @@ uint32_t ColorTypeToBufferFormat(SkColorType colorType) {
|
||||
// Hardcoding the value from android::PixelFormat
|
||||
static constexpr uint64_t kRGBA4444 = 7;
|
||||
return kRGBA4444;
|
||||
case kAlpha_8_SkColorType:
|
||||
return AHARDWAREBUFFER_FORMAT_R8_UNORM;
|
||||
default:
|
||||
ALOGV("Unsupported colorType: %d, return RGBA_8888 by default", (int)colorType);
|
||||
return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
|
||||
|
||||
Reference in New Issue
Block a user