mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1703654 - Prototype display-p3 for WebGL canvas. r=lsalzman,emilio,webidl,smaug
Enable (direct) external surface compositing for MacIOSurfaces. Works on Mac. Differential Revision: https://phabricator.services.mozilla.com/D144073
This commit is contained in:
parent
2fc91917b4
commit
e722cdd3ed
@ -837,11 +837,19 @@ ClientWebGLContext::SetContextOptions(JSContext* cx,
|
||||
newOpts.antialias = attributes.mAntialias.Value();
|
||||
}
|
||||
|
||||
if (attributes.mColorSpace.WasPassed()) {
|
||||
newOpts.colorSpace = Some(attributes.mColorSpace.Value());
|
||||
} else if (StaticPrefs::gfx_color_management_native_srgb()) {
|
||||
newOpts.colorSpace = Some(dom::PredefinedColorSpace::Srgb);
|
||||
}
|
||||
|
||||
// Don't do antialiasing if we've disabled MSAA.
|
||||
if (!StaticPrefs::webgl_msaa_samples()) {
|
||||
newOpts.antialias = false;
|
||||
}
|
||||
|
||||
// -
|
||||
|
||||
if (mInitialOptions && *mInitialOptions != newOpts) {
|
||||
// Err if the options asked for aren't the same as what they were
|
||||
// originally.
|
||||
|
@ -113,6 +113,7 @@ bool WebGLContextOptions::operator==(const WebGLContextOptions& r) const {
|
||||
eq &= (failIfMajorPerformanceCaveat == r.failIfMajorPerformanceCaveat);
|
||||
eq &= (xrCompatible == r.xrCompatible);
|
||||
eq &= (powerPreference == r.powerPreference);
|
||||
eq &= (colorSpace == r.colorSpace);
|
||||
return eq;
|
||||
}
|
||||
|
||||
@ -875,7 +876,8 @@ bool WebGLContext::PresentInto(gl::SwapChain& swapChain) {
|
||||
if (!ValidateAndInitFB(nullptr)) return false;
|
||||
|
||||
{
|
||||
auto presenter = swapChain.Acquire(mDefaultFB->mSize);
|
||||
const auto colorSpace = gfx::ToColorSpace2(mOptions.colorSpace);
|
||||
auto presenter = swapChain.Acquire(mDefaultFB->mSize, colorSpace);
|
||||
if (!presenter) {
|
||||
GenerateWarning("Swap chain surface creation failed.");
|
||||
LoseContext();
|
||||
@ -916,7 +918,8 @@ bool WebGLContext::PresentIntoXR(gl::SwapChain& swapChain,
|
||||
const gl::MozFramebuffer& fb) {
|
||||
OnEndOfFrame();
|
||||
|
||||
auto presenter = swapChain.Acquire(fb.mSize);
|
||||
const auto colorSpace = gfx::ToColorSpace2(mOptions.colorSpace);
|
||||
auto presenter = swapChain.Acquire(fb.mSize, colorSpace);
|
||||
if (!presenter) {
|
||||
GenerateWarning("Swap chain surface creation failed.");
|
||||
LoseContext();
|
||||
@ -1002,7 +1005,9 @@ void WebGLContext::CopyToSwapChain(WebGLFramebuffer* const srcFb,
|
||||
|
||||
InitSwapChain(*gl, srcFb->mSwapChain, consumerType);
|
||||
|
||||
auto presenter = srcFb->mSwapChain.Acquire(size);
|
||||
// ColorSpace will need to be part of SwapChainOptions for DTWebgl.
|
||||
const auto colorSpace = gfx::ToColorSpace2(mOptions.colorSpace);
|
||||
auto presenter = srcFb->mSwapChain.Acquire(size, colorSpace);
|
||||
if (!presenter) {
|
||||
GenerateWarning("Swap chain surface creation failed.");
|
||||
LoseContext();
|
||||
|
@ -364,6 +364,7 @@ struct WebGLContextOptions {
|
||||
bool xrCompatible = false;
|
||||
dom::WebGLPowerPreference powerPreference =
|
||||
dom::WebGLPowerPreference::Default;
|
||||
Maybe<dom::PredefinedColorSpace> colorSpace;
|
||||
bool shouldResistFingerprinting = true;
|
||||
bool enableDebugRendererInfo = false;
|
||||
|
||||
@ -376,6 +377,26 @@ struct WebGLContextOptions {
|
||||
}
|
||||
};
|
||||
|
||||
namespace gfx {
|
||||
|
||||
inline ColorSpace2 ToColorSpace2(const Maybe<dom::PredefinedColorSpace> cs) {
|
||||
if (!cs) {
|
||||
return ColorSpace2::UNKNOWN;
|
||||
}
|
||||
|
||||
switch (*cs) {
|
||||
case dom::PredefinedColorSpace::Srgb:
|
||||
return ColorSpace2::SRGB;
|
||||
case dom::PredefinedColorSpace::Display_p3:
|
||||
return ColorSpace2::DISPLAY_P3;
|
||||
case dom::PredefinedColorSpace::EndGuard_:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("Exhaustive switch");
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
||||
// -
|
||||
|
||||
template <typename _T>
|
||||
|
@ -35,6 +35,7 @@ typedef unsigned long long GLuint64EXT;
|
||||
// The power preference settings are documented in the WebGLContextAttributes
|
||||
// section of the specification.
|
||||
enum WebGLPowerPreference { "default", "low-power", "high-performance" };
|
||||
enum PredefinedColorSpace { "srgb", "display-p3" };
|
||||
|
||||
[GenerateInit]
|
||||
dictionary WebGLContextAttributes {
|
||||
@ -51,6 +52,10 @@ dictionary WebGLContextAttributes {
|
||||
GLboolean preserveDrawingBuffer = false;
|
||||
GLboolean failIfMajorPerformanceCaveat = false;
|
||||
WebGLPowerPreference powerPreference = "default";
|
||||
|
||||
// We are experimenting here, though this should be close to where we end up.
|
||||
[Pref="webgl.colorspaces.prototype"]
|
||||
PredefinedColorSpace colorSpace; // = "srgb"; Default is gfx::ColorSpace2::UNKNOWN for now.
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker),
|
||||
|
@ -634,3 +634,27 @@ CGLError MacIOSurface::CGLTexImageIOSurface2D(
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void MacIOSurface::SetColorSpace(const mozilla::gfx::ColorSpace2 cs) const {
|
||||
Maybe<CFStringRef> str;
|
||||
switch (cs) {
|
||||
case gfx::ColorSpace2::UNKNOWN:
|
||||
break;
|
||||
case gfx::ColorSpace2::SRGB:
|
||||
str = Some(kCGColorSpaceSRGB);
|
||||
break;
|
||||
case gfx::ColorSpace2::DISPLAY_P3:
|
||||
str = Some(kCGColorSpaceDisplayP3);
|
||||
break;
|
||||
case gfx::ColorSpace2::BT601_525: // Doesn't really have a better option.
|
||||
case gfx::ColorSpace2::BT709:
|
||||
str = Some(kCGColorSpaceITUR_709);
|
||||
break;
|
||||
case gfx::ColorSpace2::BT2020:
|
||||
str = Some(kCGColorSpaceITUR_2020);
|
||||
break;
|
||||
}
|
||||
if (str) {
|
||||
IOSurfaceSetValue(mIOSurfaceRef.get(), CFSTR("IOSurfaceColorSpace"), *str);
|
||||
}
|
||||
}
|
||||
|
@ -152,6 +152,8 @@ class MacIOSurface final
|
||||
static size_t GetMaxHeight();
|
||||
CFTypeRefPtr<IOSurfaceRef> GetIOSurfaceRef() { return mIOSurfaceRef; }
|
||||
|
||||
void SetColorSpace(mozilla::gfx::ColorSpace2) const;
|
||||
|
||||
private:
|
||||
CFTypeRefPtr<IOSurfaceRef> mIOSurfaceRef;
|
||||
const bool mHasAlpha;
|
||||
|
@ -365,7 +365,7 @@ enum class ColorRange : uint8_t {
|
||||
_Last = FULL,
|
||||
};
|
||||
|
||||
// Really "YcbcrColorSpace"
|
||||
// Really "YcbcrColorColorSpace"
|
||||
enum class YUVRangedColorSpace : uint8_t {
|
||||
BT601_Narrow = 0,
|
||||
BT601_Full,
|
||||
@ -380,6 +380,23 @@ enum class YUVRangedColorSpace : uint8_t {
|
||||
Default = BT709_Narrow,
|
||||
};
|
||||
|
||||
// I can either come up with a longer "very clever" name that doesn't conflict
|
||||
// with FilterSupport.h, embrace and expand FilterSupport, or rename the old
|
||||
// one.
|
||||
// Some times Worse Is Better.
|
||||
enum class ColorSpace2 : uint8_t {
|
||||
UNKNOWN, // Eventually we will remove this.
|
||||
SRGB,
|
||||
BT601_525, // aka smpte170m NTSC
|
||||
BT709, // Same gamut as SRGB, but different gamma.
|
||||
BT601_625 =
|
||||
BT709, // aka bt470bg PAL. Basically BT709, just Xg is 0.290 not 0.300.
|
||||
BT2020,
|
||||
DISPLAY_P3,
|
||||
_First = UNKNOWN,
|
||||
_Last = DISPLAY_P3,
|
||||
};
|
||||
|
||||
struct FromYUVRangedColorSpaceT final {
|
||||
const YUVColorSpace space;
|
||||
const ColorRange range;
|
||||
|
@ -26,20 +26,27 @@ static constexpr size_t kPoolSize =
|
||||
0;
|
||||
#endif
|
||||
|
||||
UniquePtr<SwapChainPresenter> SwapChain::Acquire(const gfx::IntSize& size) {
|
||||
UniquePtr<SwapChainPresenter> SwapChain::Acquire(
|
||||
const gfx::IntSize& size, const gfx::ColorSpace2 colorSpace) {
|
||||
MOZ_ASSERT(mFactory);
|
||||
|
||||
std::shared_ptr<SharedSurface> surf;
|
||||
if (!mPool.empty() &&
|
||||
(mPool.front()->mDesc.size != size || !mPool.front()->IsValid())) {
|
||||
mPool = {};
|
||||
if (!mPool.empty()) {
|
||||
// Try reuse
|
||||
const auto& existingDesc = mPool.front()->mDesc;
|
||||
auto newDesc = existingDesc;
|
||||
newDesc.size = size;
|
||||
newDesc.colorSpace = colorSpace;
|
||||
if (newDesc != existingDesc || !mPool.front()->IsValid()) {
|
||||
mPool = {};
|
||||
}
|
||||
}
|
||||
if (kPoolSize && mPool.size() == kPoolSize) {
|
||||
surf = mPool.front();
|
||||
mPool.pop();
|
||||
}
|
||||
if (!surf) {
|
||||
auto uniquePtrSurf = mFactory->CreateShared(size);
|
||||
auto uniquePtrSurf = mFactory->CreateShared(size, colorSpace);
|
||||
if (!uniquePtrSurf) return nullptr;
|
||||
surf.reset(uniquePtrSurf.release());
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class SwapChain final {
|
||||
|
||||
void ClearPool();
|
||||
const auto& FrontBuffer() const { return mFrontBuffer; }
|
||||
UniquePtr<SwapChainPresenter> Acquire(const gfx::IntSize&);
|
||||
UniquePtr<SwapChainPresenter> Acquire(const gfx::IntSize&, gfx::ColorSpace2);
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
@ -60,9 +60,23 @@ struct PartialSharedSurfaceDesc {
|
||||
const SharedSurfaceType type;
|
||||
const layers::TextureType consumerType;
|
||||
const bool canRecycle;
|
||||
|
||||
bool operator==(const PartialSharedSurfaceDesc& rhs) const {
|
||||
return gl == rhs.gl && type == rhs.type &&
|
||||
consumerType == rhs.consumerType && canRecycle == rhs.canRecycle;
|
||||
}
|
||||
};
|
||||
struct SharedSurfaceDesc : public PartialSharedSurfaceDesc {
|
||||
gfx::IntSize size = {};
|
||||
gfx::ColorSpace2 colorSpace = gfx::ColorSpace2::UNKNOWN;
|
||||
|
||||
bool operator==(const SharedSurfaceDesc& rhs) const {
|
||||
return PartialSharedSurfaceDesc::operator==(rhs) && size == rhs.size &&
|
||||
colorSpace == rhs.colorSpace;
|
||||
}
|
||||
bool operator!=(const SharedSurfaceDesc& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
class SharedSurface {
|
||||
@ -166,8 +180,9 @@ class SurfaceFactory {
|
||||
const SharedSurfaceDesc&) = 0;
|
||||
|
||||
public:
|
||||
UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) {
|
||||
return CreateSharedImpl({mDesc, size});
|
||||
UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size,
|
||||
gfx::ColorSpace2 cs) {
|
||||
return CreateSharedImpl({mDesc, size, cs});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -60,7 +60,8 @@ class SurfaceFactory_DMABUF : public SurfaceFactory {
|
||||
}
|
||||
|
||||
bool CanCreateSurface() {
|
||||
UniquePtr<SharedSurface> test = CreateShared(gfx::IntSize(1, 1));
|
||||
UniquePtr<SharedSurface> test =
|
||||
CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB);
|
||||
return test != nullptr;
|
||||
}
|
||||
};
|
||||
|
@ -60,6 +60,10 @@ UniquePtr<SharedSurface_IOSurface> SharedSurface_IOSurface::Create(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ioSurf->SetColorSpace(desc.colorSpace);
|
||||
|
||||
// -
|
||||
|
||||
auto tex = MakeUnique<Texture>(*desc.gl);
|
||||
BackTextureWithIOSurf(desc.gl, tex->name, ioSurf);
|
||||
|
||||
|
@ -1322,8 +1322,6 @@ bool NativeLayerCA::Representation::EnqueueSurface(IOSurfaceRef aSurfaceRef) {
|
||||
CFTypeRefPtr<CGColorSpaceRef> colorSpace =
|
||||
CFTypeRefPtr<CGColorSpaceRef>::WrapUnderGetRule(CVImageBufferGetColorSpace(pixelBuffer));
|
||||
if (!colorSpace) {
|
||||
printf("VIDEO_LOG: pixel buffer created by EnqueueSurface has no color space.\n");
|
||||
|
||||
// Use our main display color space.
|
||||
colorSpace = CFTypeRefPtr<CGColorSpaceRef>::WrapUnderCreateRule(
|
||||
CGDisplayCopyColorSpace(CGMainDisplayID()));
|
||||
|
@ -11,9 +11,10 @@ using mozilla::StereoMode from "ImageTypes.h";
|
||||
using struct mozilla::null_t from "mozilla/ipc/IPCCore.h";
|
||||
using mozilla::WindowsHandle from "mozilla/ipc/IPCTypes.h";
|
||||
using mozilla::gfx::YUVColorSpace from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::ChromaSubsampling from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::ColorDepth from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::ColorRange from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::ChromaSubsampling from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::ColorSpace2 from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::SurfaceFormat from "mozilla/gfx/Types.h";
|
||||
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
|
||||
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
|
||||
|
@ -192,7 +192,7 @@ void MacIOSurfaceTextureHostOGL::PushDisplayItems(
|
||||
!(mFlags & TextureFlags::NON_PREMULTIPLIED),
|
||||
wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
|
||||
preferCompositorSurface,
|
||||
/* aSupportsExternalCompositing */ false);
|
||||
/* aSupportsExternalCompositing */ true);
|
||||
break;
|
||||
}
|
||||
case gfx::SurfaceFormat::YUV422: {
|
||||
|
@ -12670,6 +12670,11 @@
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
- name: webgl.colorspaces.prototype
|
||||
type: RelaxedAtomicBool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
- name: webgl.debug.incomplete-tex-color
|
||||
type: RelaxedAtomicUint32
|
||||
value: 0
|
||||
|
Loading…
Reference in New Issue
Block a user