2017-10-28 02:10:06 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2013-11-08 22:56:52 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
#include "MacIOSurface.h"
|
2019-08-14 14:05:47 +03:00
|
|
|
#include <IOSurface/IOSurface.h>
|
2013-11-08 22:56:52 +04:00
|
|
|
#include <OpenGL/gl.h>
|
2019-08-14 14:05:07 +03:00
|
|
|
#include <OpenGL/CGLIOSurface.h>
|
2013-11-08 07:53:54 +04:00
|
|
|
#include <QuartzCore/QuartzCore.h>
|
|
|
|
#include <dlfcn.h>
|
2016-02-23 05:26:27 +03:00
|
|
|
#include "GLConsts.h"
|
2017-05-18 17:59:07 +03:00
|
|
|
#include "GLContextCGL.h"
|
2019-07-26 11:45:20 +03:00
|
|
|
#include "mozilla/Assertions.h"
|
|
|
|
#include "mozilla/RefPtr.h"
|
2013-11-08 07:53:54 +04:00
|
|
|
|
|
|
|
using namespace mozilla;
|
|
|
|
// IOSurface signatures
|
|
|
|
#define IOSURFACE_FRAMEWORK_PATH \
|
|
|
|
"/System/Library/Frameworks/IOSurface.framework/IOSurface"
|
|
|
|
|
|
|
|
#define GET_IOSYM(dest, sym_name) \
|
|
|
|
(typeof(dest)) dlsym(sIOSurfaceFramework, sym_name)
|
|
|
|
|
|
|
|
MacIOSurfaceLib::LibraryUnloader MacIOSurfaceLib::sLibraryUnloader;
|
|
|
|
bool MacIOSurfaceLib::isLoaded = false;
|
|
|
|
void* MacIOSurfaceLib::sIOSurfaceFramework;
|
|
|
|
IOSurfaceCreateFunc MacIOSurfaceLib::sCreate;
|
|
|
|
IOSurfaceGetIDFunc MacIOSurfaceLib::sGetID;
|
|
|
|
IOSurfaceLookupFunc MacIOSurfaceLib::sLookup;
|
|
|
|
IOSurfaceGetBaseAddressFunc MacIOSurfaceLib::sGetBaseAddress;
|
2014-09-03 11:09:24 +04:00
|
|
|
IOSurfaceGetBaseAddressOfPlaneFunc MacIOSurfaceLib::sGetBaseAddressOfPlane;
|
2015-08-04 00:57:19 +03:00
|
|
|
IOSurfaceSizePlaneTFunc MacIOSurfaceLib::sWidth;
|
|
|
|
IOSurfaceSizePlaneTFunc MacIOSurfaceLib::sHeight;
|
2014-09-03 11:09:24 +04:00
|
|
|
IOSurfaceSizeTFunc MacIOSurfaceLib::sPlaneCount;
|
2015-08-04 00:57:19 +03:00
|
|
|
IOSurfaceSizePlaneTFunc MacIOSurfaceLib::sBytesPerRow;
|
2014-07-12 10:08:54 +04:00
|
|
|
IOSurfaceGetPropertyMaximumFunc MacIOSurfaceLib::sGetPropertyMaximum;
|
2014-09-03 11:09:24 +04:00
|
|
|
IOSurfaceVoidFunc MacIOSurfaceLib::sIncrementUseCount;
|
|
|
|
IOSurfaceVoidFunc MacIOSurfaceLib::sDecrementUseCount;
|
2013-11-08 07:53:54 +04:00
|
|
|
IOSurfaceLockFunc MacIOSurfaceLib::sLock;
|
|
|
|
IOSurfaceUnlockFunc MacIOSurfaceLib::sUnlock;
|
2015-08-04 00:57:19 +03:00
|
|
|
IOSurfacePixelFormatFunc MacIOSurfaceLib::sPixelFormat;
|
2013-11-08 07:53:54 +04:00
|
|
|
|
|
|
|
bool MacIOSurfaceLib::isInit() {
|
|
|
|
// Guard against trying to reload the library
|
|
|
|
// if it is not available.
|
|
|
|
if (!isLoaded) LoadLibrary();
|
|
|
|
MOZ_ASSERT(sIOSurfaceFramework);
|
|
|
|
return sIOSurfaceFramework;
|
|
|
|
}
|
|
|
|
|
|
|
|
IOSurfacePtr MacIOSurfaceLib::IOSurfaceCreate(CFDictionaryRef properties) {
|
|
|
|
return sCreate(properties);
|
|
|
|
}
|
|
|
|
|
|
|
|
IOSurfacePtr MacIOSurfaceLib::IOSurfaceLookup(IOSurfaceID aIOSurfaceID) {
|
|
|
|
return sLookup(aIOSurfaceID);
|
|
|
|
}
|
|
|
|
|
|
|
|
IOSurfaceID MacIOSurfaceLib::IOSurfaceGetID(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
return sGetID(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* MacIOSurfaceLib::IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
return sGetBaseAddress(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
void* MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(
|
|
|
|
IOSurfacePtr aIOSurfacePtr, size_t planeIndex) {
|
|
|
|
return sGetBaseAddressOfPlane(aIOSurfacePtr, planeIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t MacIOSurfaceLib::IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
return sPlaneCount(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2015-08-04 00:57:19 +03:00
|
|
|
size_t MacIOSurfaceLib::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr,
|
|
|
|
size_t plane) {
|
|
|
|
return sWidth(aIOSurfacePtr, plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2015-08-04 00:57:19 +03:00
|
|
|
size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr,
|
|
|
|
size_t plane) {
|
|
|
|
return sHeight(aIOSurfacePtr, plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2015-08-04 00:57:19 +03:00
|
|
|
size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr,
|
|
|
|
size_t plane) {
|
|
|
|
return sBytesPerRow(aIOSurfacePtr, plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2014-07-12 10:08:54 +04:00
|
|
|
size_t MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(CFStringRef property) {
|
|
|
|
return sGetPropertyMaximum(property);
|
|
|
|
}
|
|
|
|
|
2015-08-04 00:57:19 +03:00
|
|
|
OSType MacIOSurfaceLib::IOSurfaceGetPixelFormat(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
return sPixelFormat(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
|
|
|
|
uint32_t options, uint32_t* seed) {
|
2013-11-08 07:53:54 +04:00
|
|
|
return sLock(aIOSurfacePtr, options, seed);
|
|
|
|
}
|
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
|
2013-11-08 07:53:54 +04:00
|
|
|
uint32_t options, uint32_t* seed) {
|
|
|
|
return sUnlock(aIOSurfacePtr, options, seed);
|
|
|
|
}
|
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
void MacIOSurfaceLib::IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
sIncrementUseCount(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacIOSurfaceLib::IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr) {
|
|
|
|
sDecrementUseCount(aIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
void MacIOSurfaceLib::LoadLibrary() {
|
|
|
|
if (isLoaded) {
|
|
|
|
return;
|
2017-07-21 05:18:50 +03:00
|
|
|
}
|
2013-11-08 07:53:54 +04:00
|
|
|
isLoaded = true;
|
|
|
|
sIOSurfaceFramework =
|
|
|
|
dlopen(IOSURFACE_FRAMEWORK_PATH, RTLD_LAZY | RTLD_LOCAL);
|
|
|
|
|
2019-08-14 14:05:24 +03:00
|
|
|
if (!sIOSurfaceFramework) {
|
2013-11-08 07:53:54 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sCreate = GET_IOSYM(sCreate, "IOSurfaceCreate");
|
|
|
|
sGetID = GET_IOSYM(sGetID, "IOSurfaceGetID");
|
2015-08-04 00:57:19 +03:00
|
|
|
sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidthOfPlane");
|
|
|
|
sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeightOfPlane");
|
|
|
|
sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRowOfPlane");
|
2014-07-12 10:08:54 +04:00
|
|
|
sGetPropertyMaximum =
|
|
|
|
GET_IOSYM(sGetPropertyMaximum, "IOSurfaceGetPropertyMaximum");
|
2013-11-08 07:53:54 +04:00
|
|
|
sLookup = GET_IOSYM(sLookup, "IOSurfaceLookup");
|
|
|
|
sLock = GET_IOSYM(sLock, "IOSurfaceLock");
|
|
|
|
sUnlock = GET_IOSYM(sUnlock, "IOSurfaceUnlock");
|
2014-09-03 11:09:24 +04:00
|
|
|
sIncrementUseCount =
|
|
|
|
GET_IOSYM(sIncrementUseCount, "IOSurfaceIncrementUseCount");
|
|
|
|
sDecrementUseCount =
|
|
|
|
GET_IOSYM(sDecrementUseCount, "IOSurfaceDecrementUseCount");
|
2013-11-08 07:53:54 +04:00
|
|
|
sGetBaseAddress = GET_IOSYM(sGetBaseAddress, "IOSurfaceGetBaseAddress");
|
2014-09-03 11:09:24 +04:00
|
|
|
sGetBaseAddressOfPlane =
|
|
|
|
GET_IOSYM(sGetBaseAddressOfPlane, "IOSurfaceGetBaseAddressOfPlane");
|
|
|
|
sPlaneCount = GET_IOSYM(sPlaneCount, "IOSurfaceGetPlaneCount");
|
2015-08-04 00:57:19 +03:00
|
|
|
sPixelFormat = GET_IOSYM(sPixelFormat, "IOSurfaceGetPixelFormat");
|
2014-09-03 11:09:24 +04:00
|
|
|
|
2019-08-14 14:05:07 +03:00
|
|
|
if (!sCreate || !sGetID || !sLookup || !sGetBaseAddress ||
|
2019-08-14 14:05:47 +03:00
|
|
|
!sGetBaseAddressOfPlane || !sPlaneCount || !sLock || !sUnlock ||
|
2014-09-03 11:09:24 +04:00
|
|
|
!sIncrementUseCount || !sDecrementUseCount || !sWidth || !sHeight ||
|
2019-08-14 14:05:47 +03:00
|
|
|
!sBytesPerRow || !sGetPropertyMaximum) {
|
2013-11-08 07:53:54 +04:00
|
|
|
CloseLibrary();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacIOSurfaceLib::CloseLibrary() {
|
|
|
|
if (sIOSurfaceFramework) {
|
|
|
|
dlclose(sIOSurfaceFramework);
|
|
|
|
}
|
|
|
|
sIOSurfaceFramework = nullptr;
|
2014-09-03 11:09:24 +04:00
|
|
|
}
|
|
|
|
|
2017-07-21 05:18:50 +03:00
|
|
|
MacIOSurface::MacIOSurface(IOSurfacePtr aIOSurfacePtr,
|
2019-04-11 15:36:31 +03:00
|
|
|
double aContentsScaleFactor, bool aHasAlpha,
|
|
|
|
gfx::YUVColorSpace aColorSpace)
|
2014-09-03 11:09:24 +04:00
|
|
|
: mIOSurfacePtr(aIOSurfacePtr),
|
|
|
|
mContentsScaleFactor(aContentsScaleFactor),
|
2019-04-11 15:36:31 +03:00
|
|
|
mHasAlpha(aHasAlpha),
|
|
|
|
mColorSpace(aColorSpace) {
|
2014-09-03 11:09:24 +04:00
|
|
|
CFRetain(mIOSurfacePtr);
|
|
|
|
IncrementUseCount();
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
MacIOSurface::~MacIOSurface() {
|
2014-09-03 11:09:24 +04:00
|
|
|
DecrementUseCount();
|
2013-11-08 07:53:54 +04:00
|
|
|
CFRelease(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
/* static */
|
2015-06-17 17:00:52 +03:00
|
|
|
already_AddRefed<MacIOSurface> MacIOSurface::CreateIOSurface(
|
2013-11-08 07:53:54 +04:00
|
|
|
int aWidth, int aHeight, double aContentsScaleFactor, bool aHasAlpha) {
|
|
|
|
if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0) return nullptr;
|
|
|
|
|
|
|
|
CFMutableDictionaryRef props = ::CFDictionaryCreateMutable(
|
|
|
|
kCFAllocatorDefault, 4, &kCFTypeDictionaryKeyCallBacks,
|
|
|
|
&kCFTypeDictionaryValueCallBacks);
|
|
|
|
if (!props) return nullptr;
|
|
|
|
|
2014-07-12 10:08:54 +04:00
|
|
|
MOZ_ASSERT((size_t)aWidth <= GetMaxWidth());
|
|
|
|
MOZ_ASSERT((size_t)aHeight <= GetMaxHeight());
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
int32_t bytesPerElem = 4;
|
|
|
|
size_t intScaleFactor = ceil(aContentsScaleFactor);
|
|
|
|
aWidth *= intScaleFactor;
|
|
|
|
aHeight *= intScaleFactor;
|
|
|
|
CFNumberRef cfWidth = ::CFNumberCreate(nullptr, kCFNumberSInt32Type, &aWidth);
|
|
|
|
CFNumberRef cfHeight =
|
|
|
|
::CFNumberCreate(nullptr, kCFNumberSInt32Type, &aHeight);
|
|
|
|
CFNumberRef cfBytesPerElem =
|
|
|
|
::CFNumberCreate(nullptr, kCFNumberSInt32Type, &bytesPerElem);
|
2019-08-14 14:05:47 +03:00
|
|
|
::CFDictionaryAddValue(props, kIOSurfaceWidth, cfWidth);
|
2013-11-08 07:53:54 +04:00
|
|
|
::CFRelease(cfWidth);
|
2019-08-14 14:05:47 +03:00
|
|
|
::CFDictionaryAddValue(props, kIOSurfaceHeight, cfHeight);
|
2013-11-08 07:53:54 +04:00
|
|
|
::CFRelease(cfHeight);
|
2019-08-14 14:05:47 +03:00
|
|
|
::CFDictionaryAddValue(props, kIOSurfaceBytesPerElement, cfBytesPerElem);
|
2013-11-08 07:53:54 +04:00
|
|
|
::CFRelease(cfBytesPerElem);
|
2019-08-14 14:05:47 +03:00
|
|
|
::CFDictionaryAddValue(props, kIOSurfaceIsGlobal, kCFBooleanTrue);
|
2013-11-08 07:53:54 +04:00
|
|
|
|
|
|
|
IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceCreate(props);
|
|
|
|
::CFRelease(props);
|
|
|
|
|
|
|
|
if (!surfaceRef) return nullptr;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<MacIOSurface> ioSurface =
|
|
|
|
new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
|
2013-11-08 07:53:54 +04:00
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
// Release the IOSurface because MacIOSurface retained it
|
|
|
|
CFRelease(surfaceRef);
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
return ioSurface.forget();
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
/* static */
|
2015-06-17 17:00:52 +03:00
|
|
|
already_AddRefed<MacIOSurface> MacIOSurface::LookupSurface(
|
2019-04-11 15:36:31 +03:00
|
|
|
IOSurfaceID aIOSurfaceID, double aContentsScaleFactor, bool aHasAlpha,
|
|
|
|
gfx::YUVColorSpace aColorSpace) {
|
2013-11-08 07:53:54 +04:00
|
|
|
if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0) return nullptr;
|
|
|
|
|
|
|
|
IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceLookup(aIOSurfaceID);
|
|
|
|
if (!surfaceRef) return nullptr;
|
|
|
|
|
2019-04-11 15:36:31 +03:00
|
|
|
RefPtr<MacIOSurface> ioSurface = new MacIOSurface(
|
|
|
|
surfaceRef, aContentsScaleFactor, aHasAlpha, aColorSpace);
|
2014-09-03 11:09:24 +04:00
|
|
|
|
|
|
|
// Release the IOSurface because MacIOSurface retained it
|
|
|
|
CFRelease(surfaceRef);
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
return ioSurface.forget();
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
IOSurfaceID MacIOSurface::GetIOSurfaceID() const {
|
2013-11-08 07:53:54 +04:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetID(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
void* MacIOSurface::GetBaseAddress() const {
|
2013-11-08 07:53:54 +04:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
void* MacIOSurface::GetBaseAddressOfPlane(size_t aPlaneIndex) const {
|
2014-09-03 11:09:24 +04:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(mIOSurfacePtr,
|
|
|
|
aPlaneIndex);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetWidth(size_t plane) const {
|
2013-11-08 07:53:54 +04:00
|
|
|
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
2015-08-04 00:57:19 +03:00
|
|
|
return GetDevicePixelWidth(plane) / intScaleFactor;
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetHeight(size_t plane) const {
|
2013-11-08 07:53:54 +04:00
|
|
|
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
2015-08-04 00:57:19 +03:00
|
|
|
return GetDevicePixelHeight(plane) / intScaleFactor;
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetPlaneCount() const {
|
2014-09-03 11:09:24 +04:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetPlaneCount(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/*static*/
|
|
|
|
size_t MacIOSurface::GetMaxWidth() {
|
2015-01-15 01:24:09 +03:00
|
|
|
if (!MacIOSurfaceLib::isInit()) return -1;
|
2019-08-14 14:05:47 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(kIOSurfaceWidth);
|
2014-07-12 10:08:54 +04:00
|
|
|
}
|
|
|
|
|
2019-02-26 01:07:19 +03:00
|
|
|
/*static*/
|
|
|
|
size_t MacIOSurface::GetMaxHeight() {
|
2015-01-15 01:24:09 +03:00
|
|
|
if (!MacIOSurfaceLib::isInit()) return -1;
|
2019-08-14 14:05:47 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(kIOSurfaceHeight);
|
2014-07-12 10:08:54 +04:00
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetDevicePixelWidth(size_t plane) const {
|
2015-08-04 00:57:19 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetWidth(mIOSurfacePtr, plane);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetDevicePixelHeight(size_t plane) const {
|
2015-08-04 00:57:19 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr, plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
size_t MacIOSurface::GetBytesPerRow(size_t plane) const {
|
2015-08-04 00:57:19 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr, plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
OSType MacIOSurface::GetPixelFormat() const {
|
2015-08-04 00:57:19 +03:00
|
|
|
return MacIOSurfaceLib::IOSurfaceGetPixelFormat(mIOSurfacePtr);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2014-09-03 11:09:24 +04:00
|
|
|
void MacIOSurface::IncrementUseCount() {
|
|
|
|
MacIOSurfaceLib::IOSurfaceIncrementUseCount(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MacIOSurface::DecrementUseCount() {
|
|
|
|
MacIOSurfaceLib::IOSurfaceDecrementUseCount(mIOSurfacePtr);
|
|
|
|
}
|
|
|
|
|
2013-11-08 07:53:54 +04:00
|
|
|
#define READ_ONLY 0x1
|
2016-06-27 18:25:13 +03:00
|
|
|
void MacIOSurface::Lock(bool aReadOnly) {
|
|
|
|
MacIOSurfaceLib::IOSurfaceLock(mIOSurfacePtr, aReadOnly ? READ_ONLY : 0,
|
|
|
|
nullptr);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
2016-06-27 18:25:13 +03:00
|
|
|
void MacIOSurface::Unlock(bool aReadOnly) {
|
|
|
|
MacIOSurfaceLib::IOSurfaceUnlock(mIOSurfacePtr, aReadOnly ? READ_ONLY : 0,
|
|
|
|
nullptr);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
using mozilla::gfx::IntSize;
|
|
|
|
using mozilla::gfx::SourceSurface;
|
|
|
|
using mozilla::gfx::SurfaceFormat;
|
|
|
|
|
2019-02-17 05:08:30 +03:00
|
|
|
static void MacIOSurfaceBufferDeallocator(void* aClosure) {
|
2016-05-09 01:33:00 +03:00
|
|
|
MOZ_ASSERT(aClosure);
|
|
|
|
|
|
|
|
delete[] static_cast<unsigned char*>(aClosure);
|
|
|
|
}
|
|
|
|
|
2015-06-17 17:00:52 +03:00
|
|
|
already_AddRefed<SourceSurface> MacIOSurface::GetAsSurface() {
|
2013-11-08 07:53:54 +04:00
|
|
|
Lock();
|
|
|
|
size_t bytesPerRow = GetBytesPerRow();
|
|
|
|
size_t ioWidth = GetDevicePixelWidth();
|
|
|
|
size_t ioHeight = GetDevicePixelHeight();
|
|
|
|
|
|
|
|
unsigned char* ioData = (unsigned char*)GetBaseAddress();
|
2016-11-15 12:00:08 +03:00
|
|
|
auto* dataCpy =
|
2016-05-09 01:33:00 +03:00
|
|
|
new unsigned char[bytesPerRow * ioHeight / sizeof(unsigned char)];
|
2013-11-08 07:53:54 +04:00
|
|
|
for (size_t i = 0; i < ioHeight; i++) {
|
|
|
|
memcpy(dataCpy + i * bytesPerRow, ioData + i * bytesPerRow, ioWidth * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
Unlock();
|
|
|
|
|
2014-01-10 23:06:16 +04:00
|
|
|
SurfaceFormat format = HasAlpha() ? mozilla::gfx::SurfaceFormat::B8G8R8A8
|
|
|
|
: mozilla::gfx::SurfaceFormat::B8G8R8X8;
|
2013-11-08 07:53:54 +04:00
|
|
|
|
2016-05-09 01:33:00 +03:00
|
|
|
RefPtr<mozilla::gfx::DataSourceSurface> surf =
|
|
|
|
mozilla::gfx::Factory::CreateWrappingDataSourceSurface(
|
|
|
|
dataCpy, bytesPerRow, IntSize(ioWidth, ioHeight), format,
|
|
|
|
&MacIOSurfaceBufferDeallocator, static_cast<void*>(dataCpy));
|
2013-11-08 07:53:54 +04:00
|
|
|
|
|
|
|
return surf.forget();
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
SurfaceFormat MacIOSurface::GetFormat() const {
|
2015-08-04 00:57:19 +03:00
|
|
|
OSType pixelFormat = GetPixelFormat();
|
2019-07-26 11:45:35 +03:00
|
|
|
if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
|
|
|
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
2015-08-04 00:57:19 +03:00
|
|
|
return SurfaceFormat::NV12;
|
2019-07-26 11:45:35 +03:00
|
|
|
} else if (pixelFormat == kCVPixelFormatType_422YpCbCr8) {
|
2016-02-23 05:26:27 +03:00
|
|
|
return SurfaceFormat::YUV422;
|
|
|
|
} else {
|
|
|
|
return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:45:20 +03:00
|
|
|
SurfaceFormat MacIOSurface::GetReadFormat() const {
|
2016-02-23 05:26:27 +03:00
|
|
|
OSType pixelFormat = GetPixelFormat();
|
2019-07-26 11:45:35 +03:00
|
|
|
if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
|
|
|
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
2016-02-23 05:26:27 +03:00
|
|
|
return SurfaceFormat::NV12;
|
2019-07-26 11:45:35 +03:00
|
|
|
} else if (pixelFormat == kCVPixelFormatType_422YpCbCr8) {
|
2016-02-23 05:26:27 +03:00
|
|
|
return SurfaceFormat::R8G8B8X8;
|
2015-08-04 00:57:19 +03:00
|
|
|
} else {
|
|
|
|
return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-21 05:18:50 +03:00
|
|
|
CGLError MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx, GLenum target,
|
|
|
|
GLenum internalFormat,
|
|
|
|
GLsizei width, GLsizei height,
|
|
|
|
GLenum format, GLenum type,
|
|
|
|
GLuint plane) const {
|
2019-08-14 14:05:07 +03:00
|
|
|
return ::CGLTexImageIOSurface2D(ctx, target, internalFormat, width, height,
|
|
|
|
format, type, (IOSurfaceRef)mIOSurfacePtr,
|
|
|
|
plane);
|
2017-07-21 05:18:50 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-05-18 17:59:07 +03:00
|
|
|
CGLError MacIOSurface::CGLTexImageIOSurface2D(
|
|
|
|
mozilla::gl::GLContext* aGL, CGLContextObj ctx, size_t plane,
|
|
|
|
mozilla::gfx::SurfaceFormat* aOutReadFormat) {
|
2015-08-04 00:57:19 +03:00
|
|
|
MOZ_ASSERT(plane >= 0);
|
2017-05-18 17:59:07 +03:00
|
|
|
bool isCompatibilityProfile = aGL->IsCompatibilityProfile();
|
2015-08-04 00:57:19 +03:00
|
|
|
OSType pixelFormat = GetPixelFormat();
|
|
|
|
|
|
|
|
GLenum internalFormat;
|
|
|
|
GLenum format;
|
|
|
|
GLenum type;
|
2019-07-26 11:45:35 +03:00
|
|
|
if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
|
|
|
|
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
|
2015-08-04 00:57:19 +03:00
|
|
|
MOZ_ASSERT(GetPlaneCount() == 2);
|
|
|
|
MOZ_ASSERT(plane < 2);
|
|
|
|
|
2017-05-18 17:59:07 +03:00
|
|
|
// The LOCAL_GL_LUMINANCE and LOCAL_GL_LUMINANCE_ALPHA are the deprecated
|
|
|
|
// format. So, use LOCAL_GL_RED and LOCAL_GL_RB if we use core profile.
|
|
|
|
// https://www.khronos.org/opengl/wiki/Image_Format#Legacy_Image_Formats
|
2015-08-04 00:57:19 +03:00
|
|
|
if (plane == 0) {
|
2017-05-18 17:59:07 +03:00
|
|
|
internalFormat = format =
|
|
|
|
(isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE) : (LOCAL_GL_RED);
|
2015-08-04 00:57:19 +03:00
|
|
|
} else {
|
2017-05-18 17:59:07 +03:00
|
|
|
internalFormat = format =
|
|
|
|
(isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE_ALPHA) : (LOCAL_GL_RG);
|
|
|
|
}
|
|
|
|
type = LOCAL_GL_UNSIGNED_BYTE;
|
|
|
|
if (aOutReadFormat) {
|
|
|
|
*aOutReadFormat = mozilla::gfx::SurfaceFormat::NV12;
|
2015-08-04 00:57:19 +03:00
|
|
|
}
|
2019-07-26 11:45:35 +03:00
|
|
|
} else if (pixelFormat == kCVPixelFormatType_422YpCbCr8) {
|
2016-02-23 05:26:27 +03:00
|
|
|
MOZ_ASSERT(plane == 0);
|
2017-05-18 17:59:07 +03:00
|
|
|
// The YCBCR_422_APPLE ext is only available in compatibility profile. So,
|
|
|
|
// we should use RGB_422_APPLE for core profile. The difference between
|
|
|
|
// YCBCR_422_APPLE and RGB_422_APPLE is that the YCBCR_422_APPLE converts
|
|
|
|
// the YCbCr value to RGB with REC 601 conversion. But the RGB_422_APPLE
|
|
|
|
// doesn't contain color conversion. You should do the color conversion by
|
|
|
|
// yourself for RGB_422_APPLE.
|
|
|
|
//
|
|
|
|
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_ycbcr_422.txt
|
|
|
|
// https://www.khronos.org/registry/OpenGL/extensions/APPLE/APPLE_rgb_422.txt
|
|
|
|
if (isCompatibilityProfile) {
|
|
|
|
format = LOCAL_GL_YCBCR_422_APPLE;
|
|
|
|
if (aOutReadFormat) {
|
|
|
|
*aOutReadFormat = mozilla::gfx::SurfaceFormat::R8G8B8X8;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
format = LOCAL_GL_RGB_422_APPLE;
|
|
|
|
if (aOutReadFormat) {
|
|
|
|
*aOutReadFormat = mozilla::gfx::SurfaceFormat::YUV422;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
internalFormat = LOCAL_GL_RGB;
|
|
|
|
type = LOCAL_GL_UNSIGNED_SHORT_8_8_APPLE;
|
2015-08-04 00:57:19 +03:00
|
|
|
} else {
|
|
|
|
MOZ_ASSERT(plane == 0);
|
|
|
|
|
2017-05-18 17:59:07 +03:00
|
|
|
internalFormat = HasAlpha() ? LOCAL_GL_RGBA : LOCAL_GL_RGB;
|
|
|
|
format = LOCAL_GL_BGRA;
|
|
|
|
type = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV;
|
|
|
|
if (aOutReadFormat) {
|
|
|
|
*aOutReadFormat = HasAlpha() ? mozilla::gfx::SurfaceFormat::R8G8B8A8
|
|
|
|
: mozilla::gfx::SurfaceFormat::R8G8B8X8;
|
|
|
|
}
|
2015-08-04 00:57:19 +03:00
|
|
|
}
|
2017-05-18 17:59:07 +03:00
|
|
|
|
2017-07-21 05:18:50 +03:00
|
|
|
return CGLTexImageIOSurface2D(ctx, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
|
|
|
|
internalFormat, GetDevicePixelWidth(plane),
|
|
|
|
GetDevicePixelHeight(plane), format, type,
|
|
|
|
plane);
|
2013-11-08 07:53:54 +04:00
|
|
|
}
|