forked from mirrors/gecko-dev
		
	 126bd9e1a4
			
		
	
	
		126bd9e1a4
		
	
	
	
	
		
			
			This patch was generated automatically by the "modeline.py" script, available here: https://github.com/amccreight/moz-source-tools/blob/master/modeline.py For every file that is modified in this patch, the changes are as follows: (1) The patch changes the file to use the exact C++ mode lines from the Mozilla coding style guide, available here: https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Coding_Style#Mode_Line (2) The patch deletes any blank lines between the mode line & the MPL boilerplate comment. (3) If the file previously had the mode lines and MPL boilerplate in a single contiguous C++ comment, then the patch splits them into separate C++ comments, to match the boilerplate in the coding style. MozReview-Commit-ID: 77D61xpSmIl --HG-- extra : rebase_source : c6162fa3cf539a07177a19838324bf368faa162b
		
			
				
	
	
		
			654 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			654 lines
		
	
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* 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/. */
 | |
| 
 | |
| #include "MacIOSurface.h"
 | |
| #include <OpenGL/gl.h>
 | |
| #include <QuartzCore/QuartzCore.h>
 | |
| #include <dlfcn.h>
 | |
| #include "mozilla/RefPtr.h"
 | |
| #include "mozilla/Assertions.h"
 | |
| #include "GLConsts.h"
 | |
| #include "GLContextCGL.h"
 | |
| 
 | |
| using namespace mozilla;
 | |
| // IOSurface signatures
 | |
| #define IOSURFACE_FRAMEWORK_PATH \
 | |
|   "/System/Library/Frameworks/IOSurface.framework/IOSurface"
 | |
| #define OPENGL_FRAMEWORK_PATH \
 | |
|   "/System/Library/Frameworks/OpenGL.framework/OpenGL"
 | |
| #define COREGRAPHICS_FRAMEWORK_PATH \
 | |
|   "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
 | |
|   "CoreGraphics.framework/CoreGraphics"
 | |
| #define COREVIDEO_FRAMEWORK_PATH \
 | |
|   "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/" \
 | |
|   "CoreVideo.framework/CoreVideo"
 | |
| 
 | |
| #define GET_CONST(const_name) \
 | |
|   ((CFStringRef*) dlsym(sIOSurfaceFramework, const_name))
 | |
| #define GET_IOSYM(dest,sym_name) \
 | |
|   (typeof(dest)) dlsym(sIOSurfaceFramework, sym_name)
 | |
| #define GET_CGLSYM(dest,sym_name) \
 | |
|   (typeof(dest)) dlsym(sOpenGLFramework, sym_name)
 | |
| #define GET_CGSYM(dest,sym_name) \
 | |
|   (typeof(dest)) dlsym(sCoreGraphicsFramework, sym_name)
 | |
| #define GET_CVSYM(dest, sym_name) \
 | |
|   (typeof(dest)) dlsym(sCoreVideoFramework, sym_name)
 | |
| 
 | |
| MacIOSurfaceLib::LibraryUnloader MacIOSurfaceLib::sLibraryUnloader;
 | |
| bool                          MacIOSurfaceLib::isLoaded = false;
 | |
| void*                         MacIOSurfaceLib::sIOSurfaceFramework;
 | |
| void*                         MacIOSurfaceLib::sOpenGLFramework;
 | |
| void*                         MacIOSurfaceLib::sCoreGraphicsFramework;
 | |
| void*                         MacIOSurfaceLib::sCoreVideoFramework;
 | |
| IOSurfaceCreateFunc           MacIOSurfaceLib::sCreate;
 | |
| IOSurfaceGetIDFunc            MacIOSurfaceLib::sGetID;
 | |
| IOSurfaceLookupFunc           MacIOSurfaceLib::sLookup;
 | |
| IOSurfaceGetBaseAddressFunc   MacIOSurfaceLib::sGetBaseAddress;
 | |
| IOSurfaceGetBaseAddressOfPlaneFunc  MacIOSurfaceLib::sGetBaseAddressOfPlane;
 | |
| IOSurfaceSizePlaneTFunc       MacIOSurfaceLib::sWidth;
 | |
| IOSurfaceSizePlaneTFunc       MacIOSurfaceLib::sHeight;
 | |
| IOSurfaceSizeTFunc            MacIOSurfaceLib::sPlaneCount;
 | |
| IOSurfaceSizePlaneTFunc       MacIOSurfaceLib::sBytesPerRow;
 | |
| IOSurfaceGetPropertyMaximumFunc   MacIOSurfaceLib::sGetPropertyMaximum;
 | |
| IOSurfaceVoidFunc             MacIOSurfaceLib::sIncrementUseCount;
 | |
| IOSurfaceVoidFunc             MacIOSurfaceLib::sDecrementUseCount;
 | |
| IOSurfaceLockFunc             MacIOSurfaceLib::sLock;
 | |
| IOSurfaceUnlockFunc           MacIOSurfaceLib::sUnlock;
 | |
| CGLTexImageIOSurface2DFunc    MacIOSurfaceLib::sTexImage;
 | |
| IOSurfaceContextCreateFunc    MacIOSurfaceLib::sIOSurfaceContextCreate;
 | |
| IOSurfaceContextCreateImageFunc   MacIOSurfaceLib::sIOSurfaceContextCreateImage;
 | |
| IOSurfaceContextGetSurfaceFunc    MacIOSurfaceLib::sIOSurfaceContextGetSurface;
 | |
| CVPixelBufferGetIOSurfaceFunc MacIOSurfaceLib::sCVPixelBufferGetIOSurface;
 | |
| unsigned int                  (*MacIOSurfaceLib::sCGContextGetTypePtr) (CGContextRef) = nullptr;
 | |
| IOSurfacePixelFormatFunc      MacIOSurfaceLib::sPixelFormat;
 | |
| 
 | |
| CFStringRef                   MacIOSurfaceLib::kPropWidth;
 | |
| CFStringRef                   MacIOSurfaceLib::kPropHeight;
 | |
| CFStringRef                   MacIOSurfaceLib::kPropBytesPerElem;
 | |
| CFStringRef                   MacIOSurfaceLib::kPropBytesPerRow;
 | |
| CFStringRef                   MacIOSurfaceLib::kPropIsGlobal;
 | |
| 
 | |
| 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);
 | |
| }
 | |
| 
 | |
| void* MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(IOSurfacePtr aIOSurfacePtr,
 | |
|                                                       size_t planeIndex) {
 | |
|   return sGetBaseAddressOfPlane(aIOSurfacePtr, planeIndex);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurfaceLib::IOSurfaceGetPlaneCount(IOSurfacePtr aIOSurfacePtr) {
 | |
|   return sPlaneCount(aIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurfaceLib::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr, size_t plane) {
 | |
|   return sWidth(aIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr, size_t plane) {
 | |
|   return sHeight(aIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr, size_t plane) {
 | |
|   return sBytesPerRow(aIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(CFStringRef property) {
 | |
|   return sGetPropertyMaximum(property);
 | |
| }
 | |
| 
 | |
| OSType MacIOSurfaceLib::IOSurfaceGetPixelFormat(IOSurfacePtr aIOSurfacePtr) {
 | |
|   return sPixelFormat(aIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr,
 | |
|                                        uint32_t options, uint32_t* seed) {
 | |
|   return sLock(aIOSurfacePtr, options, seed);
 | |
| }
 | |
| 
 | |
| IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr,
 | |
|                                          uint32_t options, uint32_t *seed) {
 | |
|   return sUnlock(aIOSurfacePtr, options, seed);
 | |
| }
 | |
| 
 | |
| void MacIOSurfaceLib::IOSurfaceIncrementUseCount(IOSurfacePtr aIOSurfacePtr) {
 | |
|   sIncrementUseCount(aIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| void MacIOSurfaceLib::IOSurfaceDecrementUseCount(IOSurfacePtr aIOSurfacePtr) {
 | |
|   sDecrementUseCount(aIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| CGLError MacIOSurfaceLib::CGLTexImageIOSurface2D(CGLContextObj ctxt,
 | |
|                              GLenum target, GLenum internalFormat,
 | |
|                              GLsizei width, GLsizei height,
 | |
|                              GLenum format, GLenum type,
 | |
|                              IOSurfacePtr ioSurface, GLuint plane) {
 | |
|   return sTexImage(ctxt, target, internalFormat, width, height,
 | |
|                    format, type, ioSurface, plane);
 | |
| }
 | |
| 
 | |
| IOSurfacePtr MacIOSurfaceLib::CVPixelBufferGetIOSurface(CVPixelBufferRef aPixelBuffer) {
 | |
|   return sCVPixelBufferGetIOSurface(aPixelBuffer);
 | |
| }
 | |
| 
 | |
| CGContextRef MacIOSurfaceLib::IOSurfaceContextCreate(IOSurfacePtr aIOSurfacePtr,
 | |
|                              unsigned aWidth, unsigned aHeight,
 | |
|                              unsigned aBitsPerComponent, unsigned aBytes,
 | |
|                              CGColorSpaceRef aColorSpace, CGBitmapInfo bitmapInfo) {
 | |
|   if (!sIOSurfaceContextCreate)
 | |
|     return nullptr;
 | |
|   return sIOSurfaceContextCreate(aIOSurfacePtr, aWidth, aHeight, aBitsPerComponent, aBytes, aColorSpace, bitmapInfo);
 | |
| }
 | |
| 
 | |
| CGImageRef MacIOSurfaceLib::IOSurfaceContextCreateImage(CGContextRef aContext) {
 | |
|   if (!sIOSurfaceContextCreateImage)
 | |
|     return nullptr;
 | |
|   return sIOSurfaceContextCreateImage(aContext);
 | |
| }
 | |
| 
 | |
| IOSurfacePtr MacIOSurfaceLib::IOSurfaceContextGetSurface(CGContextRef aContext) {
 | |
|   if (!sIOSurfaceContextGetSurface)
 | |
|     return nullptr;
 | |
|   return sIOSurfaceContextGetSurface(aContext);
 | |
| }
 | |
| 
 | |
| CFStringRef MacIOSurfaceLib::GetIOConst(const char* symbole) {
 | |
|   CFStringRef *address = (CFStringRef*)dlsym(sIOSurfaceFramework, symbole);
 | |
|   if (!address)
 | |
|     return nullptr;
 | |
| 
 | |
|   return *address;
 | |
| }
 | |
| 
 | |
| void MacIOSurfaceLib::LoadLibrary() {
 | |
|   if (isLoaded) {
 | |
|     return;
 | |
|   }
 | |
|   isLoaded = true;
 | |
|   sIOSurfaceFramework = dlopen(IOSURFACE_FRAMEWORK_PATH,
 | |
|                             RTLD_LAZY | RTLD_LOCAL);
 | |
|   sOpenGLFramework = dlopen(OPENGL_FRAMEWORK_PATH,
 | |
|                             RTLD_LAZY | RTLD_LOCAL);
 | |
| 
 | |
|   sCoreGraphicsFramework = dlopen(COREGRAPHICS_FRAMEWORK_PATH,
 | |
|                             RTLD_LAZY | RTLD_LOCAL);
 | |
| 
 | |
|   sCoreVideoFramework = dlopen(COREVIDEO_FRAMEWORK_PATH,
 | |
|                             RTLD_LAZY | RTLD_LOCAL);
 | |
| 
 | |
|   if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework ||
 | |
|       !sCoreVideoFramework) {
 | |
|     if (sIOSurfaceFramework)
 | |
|       dlclose(sIOSurfaceFramework);
 | |
|     if (sOpenGLFramework)
 | |
|       dlclose(sOpenGLFramework);
 | |
|     if (sCoreGraphicsFramework)
 | |
|       dlclose(sCoreGraphicsFramework);
 | |
|     if (sCoreVideoFramework)
 | |
|       dlclose(sCoreVideoFramework);
 | |
|     sIOSurfaceFramework = nullptr;
 | |
|     sOpenGLFramework = nullptr;
 | |
|     sCoreGraphicsFramework = nullptr;
 | |
|     sCoreVideoFramework = nullptr;
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   kPropWidth = GetIOConst("kIOSurfaceWidth");
 | |
|   kPropHeight = GetIOConst("kIOSurfaceHeight");
 | |
|   kPropBytesPerElem = GetIOConst("kIOSurfaceBytesPerElement");
 | |
|   kPropBytesPerRow = GetIOConst("kIOSurfaceBytesPerRow");
 | |
|   kPropIsGlobal = GetIOConst("kIOSurfaceIsGlobal");
 | |
|   sCreate = GET_IOSYM(sCreate, "IOSurfaceCreate");
 | |
|   sGetID  = GET_IOSYM(sGetID,  "IOSurfaceGetID");
 | |
|   sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidthOfPlane");
 | |
|   sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeightOfPlane");
 | |
|   sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRowOfPlane");
 | |
|   sGetPropertyMaximum = GET_IOSYM(sGetPropertyMaximum, "IOSurfaceGetPropertyMaximum");
 | |
|   sLookup = GET_IOSYM(sLookup, "IOSurfaceLookup");
 | |
|   sLock = GET_IOSYM(sLock, "IOSurfaceLock");
 | |
|   sUnlock = GET_IOSYM(sUnlock, "IOSurfaceUnlock");
 | |
|   sIncrementUseCount =
 | |
|     GET_IOSYM(sIncrementUseCount, "IOSurfaceIncrementUseCount");
 | |
|   sDecrementUseCount =
 | |
|     GET_IOSYM(sDecrementUseCount, "IOSurfaceDecrementUseCount");
 | |
|   sGetBaseAddress = GET_IOSYM(sGetBaseAddress, "IOSurfaceGetBaseAddress");
 | |
|   sGetBaseAddressOfPlane =
 | |
|     GET_IOSYM(sGetBaseAddressOfPlane, "IOSurfaceGetBaseAddressOfPlane");
 | |
|   sPlaneCount = GET_IOSYM(sPlaneCount, "IOSurfaceGetPlaneCount");
 | |
|   sPixelFormat = GET_IOSYM(sPixelFormat, "IOSurfaceGetPixelFormat");
 | |
| 
 | |
|   sTexImage = GET_CGLSYM(sTexImage, "CGLTexImageIOSurface2D");
 | |
|   sCGContextGetTypePtr = (unsigned int (*)(CGContext*))dlsym(RTLD_DEFAULT, "CGContextGetType");
 | |
| 
 | |
|   sCVPixelBufferGetIOSurface =
 | |
|     GET_CVSYM(sCVPixelBufferGetIOSurface, "CVPixelBufferGetIOSurface");
 | |
| 
 | |
|   // Optional symbols
 | |
|   sIOSurfaceContextCreate = GET_CGSYM(sIOSurfaceContextCreate, "CGIOSurfaceContextCreate");
 | |
|   sIOSurfaceContextCreateImage = GET_CGSYM(sIOSurfaceContextCreateImage, "CGIOSurfaceContextCreateImage");
 | |
|   sIOSurfaceContextGetSurface = GET_CGSYM(sIOSurfaceContextGetSurface, "CGIOSurfaceContextGetSurface");
 | |
| 
 | |
|   if (!sCreate || !sGetID || !sLookup || !sTexImage || !sGetBaseAddress ||
 | |
|       !sGetBaseAddressOfPlane || !sPlaneCount ||
 | |
|       !kPropWidth || !kPropHeight || !kPropBytesPerElem || !kPropIsGlobal ||
 | |
|       !sLock || !sUnlock || !sIncrementUseCount || !sDecrementUseCount ||
 | |
|       !sWidth || !sHeight || !kPropBytesPerRow ||
 | |
|       !sBytesPerRow || !sGetPropertyMaximum || !sCVPixelBufferGetIOSurface) {
 | |
|     CloseLibrary();
 | |
|   }
 | |
| }
 | |
| 
 | |
| void MacIOSurfaceLib::CloseLibrary() {
 | |
|   if (sIOSurfaceFramework) {
 | |
|     dlclose(sIOSurfaceFramework);
 | |
|   }
 | |
|   if (sOpenGLFramework) {
 | |
|     dlclose(sOpenGLFramework);
 | |
|   }
 | |
|   if (sCoreVideoFramework) {
 | |
|     dlclose(sCoreVideoFramework);
 | |
|   }
 | |
|   sIOSurfaceFramework = nullptr;
 | |
|   sOpenGLFramework = nullptr;
 | |
|   sCoreVideoFramework = nullptr;
 | |
| }
 | |
| 
 | |
| MacIOSurface::MacIOSurface(IOSurfacePtr aIOSurfacePtr,
 | |
|                            double aContentsScaleFactor, bool aHasAlpha)
 | |
|   : mIOSurfacePtr(aIOSurfacePtr)
 | |
|   , mContentsScaleFactor(aContentsScaleFactor)
 | |
|   , mHasAlpha(aHasAlpha)
 | |
| {
 | |
|   CFRetain(mIOSurfacePtr);
 | |
|   IncrementUseCount();
 | |
| }
 | |
| 
 | |
| MacIOSurface::~MacIOSurface() {
 | |
|   DecrementUseCount();
 | |
|   CFRelease(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| already_AddRefed<MacIOSurface> MacIOSurface::CreateIOSurface(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;
 | |
| 
 | |
|   MOZ_ASSERT((size_t)aWidth <= GetMaxWidth());
 | |
|   MOZ_ASSERT((size_t)aHeight <= GetMaxHeight());
 | |
| 
 | |
|   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);
 | |
|   ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropWidth,
 | |
|                                 cfWidth);
 | |
|   ::CFRelease(cfWidth);
 | |
|   ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropHeight,
 | |
|                                 cfHeight);
 | |
|   ::CFRelease(cfHeight);
 | |
|   ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropBytesPerElem,
 | |
|                                 cfBytesPerElem);
 | |
|   ::CFRelease(cfBytesPerElem);
 | |
|   ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropIsGlobal,
 | |
|                                 kCFBooleanTrue);
 | |
| 
 | |
|   IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceCreate(props);
 | |
|   ::CFRelease(props);
 | |
| 
 | |
|   if (!surfaceRef)
 | |
|     return nullptr;
 | |
| 
 | |
|   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
 | |
|   if (!ioSurface) {
 | |
|     ::CFRelease(surfaceRef);
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   // Release the IOSurface because MacIOSurface retained it
 | |
|   CFRelease(surfaceRef);
 | |
| 
 | |
|   return ioSurface.forget();
 | |
| }
 | |
| 
 | |
| already_AddRefed<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID,
 | |
|                                                        double aContentsScaleFactor,
 | |
|                                                        bool aHasAlpha) {
 | |
|   if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
 | |
|     return nullptr;
 | |
| 
 | |
|   IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceLookup(aIOSurfaceID);
 | |
|   if (!surfaceRef)
 | |
|     return nullptr;
 | |
| 
 | |
|   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
 | |
|   if (!ioSurface) {
 | |
|     ::CFRelease(surfaceRef);
 | |
|     return nullptr;
 | |
|   }
 | |
| 
 | |
|   // Release the IOSurface because MacIOSurface retained it
 | |
|   CFRelease(surfaceRef);
 | |
| 
 | |
|   return ioSurface.forget();
 | |
| }
 | |
| 
 | |
| IOSurfaceID MacIOSurface::GetIOSurfaceID() {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetID(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| void* MacIOSurface::GetBaseAddress() {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| void* MacIOSurface::GetBaseAddressOfPlane(size_t aPlaneIndex)
 | |
| {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetBaseAddressOfPlane(mIOSurfacePtr,
 | |
|                                                          aPlaneIndex);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetWidth(size_t plane) {
 | |
|   size_t intScaleFactor = ceil(mContentsScaleFactor);
 | |
|   return GetDevicePixelWidth(plane) / intScaleFactor;
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetHeight(size_t plane) {
 | |
|   size_t intScaleFactor = ceil(mContentsScaleFactor);
 | |
|   return GetDevicePixelHeight(plane) / intScaleFactor;
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetPlaneCount() {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetPlaneCount(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| /*static*/ size_t MacIOSurface::GetMaxWidth() {
 | |
|   if (!MacIOSurfaceLib::isInit())
 | |
|     return -1;
 | |
|   return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropWidth);
 | |
| }
 | |
| 
 | |
| /*static*/ size_t MacIOSurface::GetMaxHeight() {
 | |
|   if (!MacIOSurfaceLib::isInit())
 | |
|     return -1;
 | |
|   return MacIOSurfaceLib::IOSurfaceGetPropertyMaximum(MacIOSurfaceLib::kPropHeight);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetDevicePixelWidth(size_t plane) {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetWidth(mIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetDevicePixelHeight(size_t plane) {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| size_t MacIOSurface::GetBytesPerRow(size_t plane) {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr, plane);
 | |
| }
 | |
| 
 | |
| OSType MacIOSurface::GetPixelFormat() {
 | |
|   return MacIOSurfaceLib::IOSurfaceGetPixelFormat(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| void MacIOSurface::IncrementUseCount() {
 | |
|   MacIOSurfaceLib::IOSurfaceIncrementUseCount(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| void MacIOSurface::DecrementUseCount() {
 | |
|   MacIOSurfaceLib::IOSurfaceDecrementUseCount(mIOSurfacePtr);
 | |
| }
 | |
| 
 | |
| #define READ_ONLY 0x1
 | |
| void MacIOSurface::Lock(bool aReadOnly) {
 | |
|   MacIOSurfaceLib::IOSurfaceLock(mIOSurfacePtr, aReadOnly ? READ_ONLY : 0, nullptr);
 | |
| }
 | |
| 
 | |
| void MacIOSurface::Unlock(bool aReadOnly) {
 | |
|   MacIOSurfaceLib::IOSurfaceUnlock(mIOSurfacePtr, aReadOnly ? READ_ONLY : 0, nullptr);
 | |
| }
 | |
| 
 | |
| using mozilla::gfx::SourceSurface;
 | |
| using mozilla::gfx::IntSize;
 | |
| using mozilla::gfx::SurfaceFormat;
 | |
| 
 | |
| void
 | |
| MacIOSurfaceBufferDeallocator(void* aClosure)
 | |
| {
 | |
|   MOZ_ASSERT(aClosure);
 | |
| 
 | |
|   delete [] static_cast<unsigned char*>(aClosure);
 | |
| }
 | |
| 
 | |
| already_AddRefed<SourceSurface>
 | |
| MacIOSurface::GetAsSurface() {
 | |
|   Lock();
 | |
|   size_t bytesPerRow = GetBytesPerRow();
 | |
|   size_t ioWidth = GetDevicePixelWidth();
 | |
|   size_t ioHeight = GetDevicePixelHeight();
 | |
| 
 | |
|   unsigned char* ioData = (unsigned char*)GetBaseAddress();
 | |
|   auto *dataCpy =
 | |
|       new unsigned char[bytesPerRow * ioHeight / sizeof(unsigned char)];
 | |
|   for (size_t i = 0; i < ioHeight; i++) {
 | |
|     memcpy(dataCpy + i * bytesPerRow,
 | |
|            ioData + i * bytesPerRow, ioWidth * 4);
 | |
|   }
 | |
| 
 | |
|   Unlock();
 | |
| 
 | |
|   SurfaceFormat format = HasAlpha() ? mozilla::gfx::SurfaceFormat::B8G8R8A8 :
 | |
|                                       mozilla::gfx::SurfaceFormat::B8G8R8X8;
 | |
| 
 | |
|   RefPtr<mozilla::gfx::DataSourceSurface> surf =
 | |
|       mozilla::gfx::Factory::CreateWrappingDataSourceSurface(dataCpy,
 | |
|                                                              bytesPerRow,
 | |
|                                                              IntSize(ioWidth, ioHeight),
 | |
|                                                              format,
 | |
|                                                              &MacIOSurfaceBufferDeallocator,
 | |
|                                                              static_cast<void*>(dataCpy));
 | |
| 
 | |
|   return surf.forget();
 | |
| }
 | |
| 
 | |
| SurfaceFormat
 | |
| MacIOSurface::GetFormat()
 | |
| {
 | |
|   OSType pixelFormat = GetPixelFormat();
 | |
|   if (pixelFormat == '420v') {
 | |
|     return SurfaceFormat::NV12;
 | |
|   } else if (pixelFormat == '2vuy') {
 | |
|     return SurfaceFormat::YUV422;
 | |
|   } else  {
 | |
|     return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
 | |
|   }
 | |
| }
 | |
| 
 | |
| SurfaceFormat
 | |
| MacIOSurface::GetReadFormat()
 | |
| {
 | |
|   OSType pixelFormat = GetPixelFormat();
 | |
|   if (pixelFormat == '420v') {
 | |
|     return SurfaceFormat::NV12;
 | |
|   } else if (pixelFormat == '2vuy') {
 | |
|     return SurfaceFormat::R8G8B8X8;
 | |
|   } else  {
 | |
|     return HasAlpha() ? SurfaceFormat::R8G8B8A8 : SurfaceFormat::R8G8B8X8;
 | |
|   }
 | |
| }
 | |
| 
 | |
| CGLError
 | |
| MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx,
 | |
|                                      GLenum target, GLenum internalFormat,
 | |
|                                      GLsizei width, GLsizei height,
 | |
|                                      GLenum format, GLenum type,
 | |
|                                      GLuint plane) const
 | |
| {
 | |
|   return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx, target, internalFormat, width,
 | |
|                                                  height, format, type, mIOSurfacePtr,
 | |
|                                                  plane);
 | |
| }
 | |
| 
 | |
| CGLError
 | |
| MacIOSurface::CGLTexImageIOSurface2D(mozilla::gl::GLContext* aGL,
 | |
|                                      CGLContextObj ctx,
 | |
|                                      size_t plane,
 | |
|                                      mozilla::gfx::SurfaceFormat* aOutReadFormat)
 | |
| {
 | |
|   MOZ_ASSERT(plane >= 0);
 | |
|   bool isCompatibilityProfile = aGL->IsCompatibilityProfile();
 | |
|   OSType pixelFormat = GetPixelFormat();
 | |
| 
 | |
|   GLenum internalFormat;
 | |
|   GLenum format;
 | |
|   GLenum type;
 | |
|   if (pixelFormat == '420v') {
 | |
|     MOZ_ASSERT(GetPlaneCount() == 2);
 | |
|     MOZ_ASSERT(plane < 2);
 | |
| 
 | |
|     // 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
 | |
|     if (plane == 0) {
 | |
|       internalFormat = format = (isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE)
 | |
|                                                           : (LOCAL_GL_RED);
 | |
|     } else {
 | |
|       internalFormat = format = (isCompatibilityProfile) ? (LOCAL_GL_LUMINANCE_ALPHA)
 | |
|                                                           : (LOCAL_GL_RG);
 | |
|     }
 | |
|     type = LOCAL_GL_UNSIGNED_BYTE;
 | |
|     if (aOutReadFormat) {
 | |
|       *aOutReadFormat = mozilla::gfx::SurfaceFormat::NV12;
 | |
|     }
 | |
|   } else if (pixelFormat == '2vuy') {
 | |
|     MOZ_ASSERT(plane == 0);
 | |
|     // 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;
 | |
|   } else  {
 | |
|     MOZ_ASSERT(plane == 0);
 | |
| 
 | |
|     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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return CGLTexImageIOSurface2D(ctx, LOCAL_GL_TEXTURE_RECTANGLE_ARB, internalFormat,
 | |
|                                 GetDevicePixelWidth(plane), GetDevicePixelHeight(plane),
 | |
|                                 format, type, plane);
 | |
| }
 | |
| 
 | |
| static
 | |
| CGColorSpaceRef CreateSystemColorSpace() {
 | |
|   CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
 | |
|   if (!cspace) {
 | |
|     cspace = ::CGColorSpaceCreateDeviceRGB();
 | |
|   }
 | |
|   return cspace;
 | |
| }
 | |
| 
 | |
| CGContextRef MacIOSurface::CreateIOSurfaceContext() {
 | |
|   CGColorSpaceRef cspace = CreateSystemColorSpace();
 | |
|   CGContextRef ref = MacIOSurfaceLib::IOSurfaceContextCreate(mIOSurfacePtr,
 | |
|                                                 GetDevicePixelWidth(),
 | |
|                                                 GetDevicePixelHeight(),
 | |
|                                                 8, 32, cspace, 0x2002);
 | |
|   ::CGColorSpaceRelease(cspace);
 | |
|   return ref;
 | |
| }
 | |
| 
 | |
| CGImageRef MacIOSurface::CreateImageFromIOSurfaceContext(CGContextRef aContext) {
 | |
|   if (!MacIOSurfaceLib::isInit())
 | |
|     return nullptr;
 | |
| 
 | |
|   return MacIOSurfaceLib::IOSurfaceContextCreateImage(aContext);
 | |
| }
 | |
| 
 | |
| already_AddRefed<MacIOSurface> MacIOSurface::IOSurfaceContextGetSurface(CGContextRef aContext,
 | |
|                                                                     double aContentsScaleFactor,
 | |
|                                                                     bool aHasAlpha) {
 | |
|   if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0)
 | |
|     return nullptr;
 | |
| 
 | |
|   IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceContextGetSurface(aContext);
 | |
|   if (!surfaceRef)
 | |
|     return nullptr;
 | |
| 
 | |
|   RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha);
 | |
|   if (!ioSurface) {
 | |
|     ::CFRelease(surfaceRef);
 | |
|     return nullptr;
 | |
|   }
 | |
|   return ioSurface.forget();
 | |
| }
 | |
| 
 | |
| CGContextType GetContextType(CGContextRef ref)
 | |
| {
 | |
|   if (!MacIOSurfaceLib::isInit() || !MacIOSurfaceLib::sCGContextGetTypePtr)
 | |
|     return CG_CONTEXT_TYPE_UNKNOWN;
 | |
| 
 | |
|   unsigned int type = MacIOSurfaceLib::sCGContextGetTypePtr(ref);
 | |
|   if (type == CG_CONTEXT_TYPE_BITMAP) {
 | |
|     return CG_CONTEXT_TYPE_BITMAP;
 | |
|   } else if (type == CG_CONTEXT_TYPE_IOSURFACE) {
 | |
|     return CG_CONTEXT_TYPE_IOSURFACE;
 | |
|   } else {
 | |
|     return CG_CONTEXT_TYPE_UNKNOWN;
 | |
|   }
 | |
| }
 |