Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | // vim:set ts=2 sts=2 sw=2 et cin: |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #include "MacIOSurface.h" |
michael@0 | 8 | #include <OpenGL/gl.h> |
michael@0 | 9 | #include <QuartzCore/QuartzCore.h> |
michael@0 | 10 | #include <dlfcn.h> |
michael@0 | 11 | #include "mozilla/RefPtr.h" |
michael@0 | 12 | #include "mozilla/Assertions.h" |
michael@0 | 13 | |
michael@0 | 14 | using namespace mozilla; |
michael@0 | 15 | // IOSurface signatures |
michael@0 | 16 | #define IOSURFACE_FRAMEWORK_PATH \ |
michael@0 | 17 | "/System/Library/Frameworks/IOSurface.framework/IOSurface" |
michael@0 | 18 | #define OPENGL_FRAMEWORK_PATH \ |
michael@0 | 19 | "/System/Library/Frameworks/OpenGL.framework/OpenGL" |
michael@0 | 20 | #define COREGRAPHICS_FRAMEWORK_PATH \ |
michael@0 | 21 | "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/CoreGraphics" |
michael@0 | 22 | |
michael@0 | 23 | |
michael@0 | 24 | |
michael@0 | 25 | #define GET_CONST(const_name) \ |
michael@0 | 26 | ((CFStringRef*) dlsym(sIOSurfaceFramework, const_name)) |
michael@0 | 27 | #define GET_IOSYM(dest,sym_name) \ |
michael@0 | 28 | (typeof(dest)) dlsym(sIOSurfaceFramework, sym_name) |
michael@0 | 29 | #define GET_CGLSYM(dest,sym_name) \ |
michael@0 | 30 | (typeof(dest)) dlsym(sOpenGLFramework, sym_name) |
michael@0 | 31 | #define GET_CGSYM(dest,sym_name) \ |
michael@0 | 32 | (typeof(dest)) dlsym(sCoreGraphicsFramework, sym_name) |
michael@0 | 33 | |
michael@0 | 34 | MacIOSurfaceLib::LibraryUnloader MacIOSurfaceLib::sLibraryUnloader; |
michael@0 | 35 | bool MacIOSurfaceLib::isLoaded = false; |
michael@0 | 36 | void* MacIOSurfaceLib::sIOSurfaceFramework; |
michael@0 | 37 | void* MacIOSurfaceLib::sOpenGLFramework; |
michael@0 | 38 | void* MacIOSurfaceLib::sCoreGraphicsFramework; |
michael@0 | 39 | IOSurfaceCreateFunc MacIOSurfaceLib::sCreate; |
michael@0 | 40 | IOSurfaceGetIDFunc MacIOSurfaceLib::sGetID; |
michael@0 | 41 | IOSurfaceLookupFunc MacIOSurfaceLib::sLookup; |
michael@0 | 42 | IOSurfaceGetBaseAddressFunc MacIOSurfaceLib::sGetBaseAddress; |
michael@0 | 43 | IOSurfaceGetWidthFunc MacIOSurfaceLib::sWidth; |
michael@0 | 44 | IOSurfaceGetHeightFunc MacIOSurfaceLib::sHeight; |
michael@0 | 45 | IOSurfaceGetBytesPerRowFunc MacIOSurfaceLib::sBytesPerRow; |
michael@0 | 46 | IOSurfaceLockFunc MacIOSurfaceLib::sLock; |
michael@0 | 47 | IOSurfaceUnlockFunc MacIOSurfaceLib::sUnlock; |
michael@0 | 48 | CGLTexImageIOSurface2DFunc MacIOSurfaceLib::sTexImage; |
michael@0 | 49 | IOSurfaceContextCreateFunc MacIOSurfaceLib::sIOSurfaceContextCreate; |
michael@0 | 50 | IOSurfaceContextCreateImageFunc MacIOSurfaceLib::sIOSurfaceContextCreateImage; |
michael@0 | 51 | IOSurfaceContextGetSurfaceFunc MacIOSurfaceLib::sIOSurfaceContextGetSurface; |
michael@0 | 52 | unsigned int (*MacIOSurfaceLib::sCGContextGetTypePtr) (CGContextRef) = nullptr; |
michael@0 | 53 | |
michael@0 | 54 | CFStringRef MacIOSurfaceLib::kPropWidth; |
michael@0 | 55 | CFStringRef MacIOSurfaceLib::kPropHeight; |
michael@0 | 56 | CFStringRef MacIOSurfaceLib::kPropBytesPerElem; |
michael@0 | 57 | CFStringRef MacIOSurfaceLib::kPropBytesPerRow; |
michael@0 | 58 | CFStringRef MacIOSurfaceLib::kPropIsGlobal; |
michael@0 | 59 | |
michael@0 | 60 | bool MacIOSurfaceLib::isInit() { |
michael@0 | 61 | // Guard against trying to reload the library |
michael@0 | 62 | // if it is not available. |
michael@0 | 63 | if (!isLoaded) |
michael@0 | 64 | LoadLibrary(); |
michael@0 | 65 | MOZ_ASSERT(sIOSurfaceFramework); |
michael@0 | 66 | return sIOSurfaceFramework; |
michael@0 | 67 | } |
michael@0 | 68 | |
michael@0 | 69 | IOSurfacePtr MacIOSurfaceLib::IOSurfaceCreate(CFDictionaryRef properties) { |
michael@0 | 70 | return sCreate(properties); |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | IOSurfacePtr MacIOSurfaceLib::IOSurfaceLookup(IOSurfaceID aIOSurfaceID) { |
michael@0 | 74 | return sLookup(aIOSurfaceID); |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | IOSurfaceID MacIOSurfaceLib::IOSurfaceGetID(IOSurfacePtr aIOSurfacePtr) { |
michael@0 | 78 | return sGetID(aIOSurfacePtr); |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | void* MacIOSurfaceLib::IOSurfaceGetBaseAddress(IOSurfacePtr aIOSurfacePtr) { |
michael@0 | 82 | return sGetBaseAddress(aIOSurfacePtr); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | size_t MacIOSurfaceLib::IOSurfaceGetWidth(IOSurfacePtr aIOSurfacePtr) { |
michael@0 | 86 | return sWidth(aIOSurfacePtr); |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | size_t MacIOSurfaceLib::IOSurfaceGetHeight(IOSurfacePtr aIOSurfacePtr) { |
michael@0 | 90 | return sHeight(aIOSurfacePtr); |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | size_t MacIOSurfaceLib::IOSurfaceGetBytesPerRow(IOSurfacePtr aIOSurfacePtr) { |
michael@0 | 94 | return sBytesPerRow(aIOSurfacePtr); |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | IOReturn MacIOSurfaceLib::IOSurfaceLock(IOSurfacePtr aIOSurfacePtr, |
michael@0 | 98 | uint32_t options, uint32_t *seed) { |
michael@0 | 99 | return sLock(aIOSurfacePtr, options, seed); |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | IOReturn MacIOSurfaceLib::IOSurfaceUnlock(IOSurfacePtr aIOSurfacePtr, |
michael@0 | 103 | uint32_t options, uint32_t *seed) { |
michael@0 | 104 | return sUnlock(aIOSurfacePtr, options, seed); |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | CGLError MacIOSurfaceLib::CGLTexImageIOSurface2D(CGLContextObj ctxt, |
michael@0 | 108 | GLenum target, GLenum internalFormat, |
michael@0 | 109 | GLsizei width, GLsizei height, |
michael@0 | 110 | GLenum format, GLenum type, |
michael@0 | 111 | IOSurfacePtr ioSurface, GLuint plane) { |
michael@0 | 112 | return sTexImage(ctxt, target, internalFormat, width, height, |
michael@0 | 113 | format, type, ioSurface, plane); |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | CGContextRef MacIOSurfaceLib::IOSurfaceContextCreate(IOSurfacePtr aIOSurfacePtr, |
michael@0 | 117 | unsigned aWidth, unsigned aHeight, |
michael@0 | 118 | unsigned aBitsPerComponent, unsigned aBytes, |
michael@0 | 119 | CGColorSpaceRef aColorSpace, CGBitmapInfo bitmapInfo) { |
michael@0 | 120 | if (!sIOSurfaceContextCreate) |
michael@0 | 121 | return nullptr; |
michael@0 | 122 | return sIOSurfaceContextCreate(aIOSurfacePtr, aWidth, aHeight, aBitsPerComponent, aBytes, aColorSpace, bitmapInfo); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | CGImageRef MacIOSurfaceLib::IOSurfaceContextCreateImage(CGContextRef aContext) { |
michael@0 | 126 | if (!sIOSurfaceContextCreateImage) |
michael@0 | 127 | return nullptr; |
michael@0 | 128 | return sIOSurfaceContextCreateImage(aContext); |
michael@0 | 129 | } |
michael@0 | 130 | |
michael@0 | 131 | IOSurfacePtr MacIOSurfaceLib::IOSurfaceContextGetSurface(CGContextRef aContext) { |
michael@0 | 132 | if (!sIOSurfaceContextGetSurface) |
michael@0 | 133 | return nullptr; |
michael@0 | 134 | return sIOSurfaceContextGetSurface(aContext); |
michael@0 | 135 | } |
michael@0 | 136 | |
michael@0 | 137 | CFStringRef MacIOSurfaceLib::GetIOConst(const char* symbole) { |
michael@0 | 138 | CFStringRef *address = (CFStringRef*)dlsym(sIOSurfaceFramework, symbole); |
michael@0 | 139 | if (!address) |
michael@0 | 140 | return nullptr; |
michael@0 | 141 | |
michael@0 | 142 | return *address; |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | void MacIOSurfaceLib::LoadLibrary() { |
michael@0 | 146 | if (isLoaded) { |
michael@0 | 147 | return; |
michael@0 | 148 | } |
michael@0 | 149 | isLoaded = true; |
michael@0 | 150 | sIOSurfaceFramework = dlopen(IOSURFACE_FRAMEWORK_PATH, |
michael@0 | 151 | RTLD_LAZY | RTLD_LOCAL); |
michael@0 | 152 | sOpenGLFramework = dlopen(OPENGL_FRAMEWORK_PATH, |
michael@0 | 153 | RTLD_LAZY | RTLD_LOCAL); |
michael@0 | 154 | |
michael@0 | 155 | sCoreGraphicsFramework = dlopen(COREGRAPHICS_FRAMEWORK_PATH, |
michael@0 | 156 | RTLD_LAZY | RTLD_LOCAL); |
michael@0 | 157 | if (!sIOSurfaceFramework || !sOpenGLFramework || !sCoreGraphicsFramework) { |
michael@0 | 158 | if (sIOSurfaceFramework) |
michael@0 | 159 | dlclose(sIOSurfaceFramework); |
michael@0 | 160 | if (sOpenGLFramework) |
michael@0 | 161 | dlclose(sOpenGLFramework); |
michael@0 | 162 | if (sCoreGraphicsFramework) |
michael@0 | 163 | dlclose(sCoreGraphicsFramework); |
michael@0 | 164 | sIOSurfaceFramework = nullptr; |
michael@0 | 165 | sOpenGLFramework = nullptr; |
michael@0 | 166 | sCoreGraphicsFramework = nullptr; |
michael@0 | 167 | return; |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | kPropWidth = GetIOConst("kIOSurfaceWidth"); |
michael@0 | 171 | kPropHeight = GetIOConst("kIOSurfaceHeight"); |
michael@0 | 172 | kPropBytesPerElem = GetIOConst("kIOSurfaceBytesPerElement"); |
michael@0 | 173 | kPropBytesPerRow = GetIOConst("kIOSurfaceBytesPerRow"); |
michael@0 | 174 | kPropIsGlobal = GetIOConst("kIOSurfaceIsGlobal"); |
michael@0 | 175 | sCreate = GET_IOSYM(sCreate, "IOSurfaceCreate"); |
michael@0 | 176 | sGetID = GET_IOSYM(sGetID, "IOSurfaceGetID"); |
michael@0 | 177 | sWidth = GET_IOSYM(sWidth, "IOSurfaceGetWidth"); |
michael@0 | 178 | sHeight = GET_IOSYM(sHeight, "IOSurfaceGetHeight"); |
michael@0 | 179 | sBytesPerRow = GET_IOSYM(sBytesPerRow, "IOSurfaceGetBytesPerRow"); |
michael@0 | 180 | sLookup = GET_IOSYM(sLookup, "IOSurfaceLookup"); |
michael@0 | 181 | sLock = GET_IOSYM(sLock, "IOSurfaceLock"); |
michael@0 | 182 | sUnlock = GET_IOSYM(sUnlock, "IOSurfaceUnlock"); |
michael@0 | 183 | sGetBaseAddress = GET_IOSYM(sGetBaseAddress, "IOSurfaceGetBaseAddress"); |
michael@0 | 184 | sTexImage = GET_CGLSYM(sTexImage, "CGLTexImageIOSurface2D"); |
michael@0 | 185 | sCGContextGetTypePtr = (unsigned int (*)(CGContext*))dlsym(RTLD_DEFAULT, "CGContextGetType"); |
michael@0 | 186 | |
michael@0 | 187 | // Optional symbols |
michael@0 | 188 | sIOSurfaceContextCreate = GET_CGSYM(sIOSurfaceContextCreate, "CGIOSurfaceContextCreate"); |
michael@0 | 189 | sIOSurfaceContextCreateImage = GET_CGSYM(sIOSurfaceContextCreateImage, "CGIOSurfaceContextCreateImage"); |
michael@0 | 190 | sIOSurfaceContextGetSurface = GET_CGSYM(sIOSurfaceContextGetSurface, "CGIOSurfaceContextGetSurface"); |
michael@0 | 191 | |
michael@0 | 192 | if (!sCreate || !sGetID || !sLookup || !sTexImage || !sGetBaseAddress || |
michael@0 | 193 | !kPropWidth || !kPropHeight || !kPropBytesPerElem || !kPropIsGlobal || |
michael@0 | 194 | !sLock || !sUnlock || !sWidth || !sHeight || !kPropBytesPerRow || |
michael@0 | 195 | !sBytesPerRow) { |
michael@0 | 196 | CloseLibrary(); |
michael@0 | 197 | } |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | void MacIOSurfaceLib::CloseLibrary() { |
michael@0 | 201 | if (sIOSurfaceFramework) { |
michael@0 | 202 | dlclose(sIOSurfaceFramework); |
michael@0 | 203 | } |
michael@0 | 204 | if (sOpenGLFramework) { |
michael@0 | 205 | dlclose(sOpenGLFramework); |
michael@0 | 206 | } |
michael@0 | 207 | sIOSurfaceFramework = nullptr; |
michael@0 | 208 | sOpenGLFramework = nullptr; |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | MacIOSurface::~MacIOSurface() { |
michael@0 | 212 | CFRelease(mIOSurfacePtr); |
michael@0 | 213 | } |
michael@0 | 214 | |
michael@0 | 215 | TemporaryRef<MacIOSurface> MacIOSurface::CreateIOSurface(int aWidth, int aHeight, |
michael@0 | 216 | double aContentsScaleFactor, |
michael@0 | 217 | bool aHasAlpha) { |
michael@0 | 218 | if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0) |
michael@0 | 219 | return nullptr; |
michael@0 | 220 | |
michael@0 | 221 | CFMutableDictionaryRef props = ::CFDictionaryCreateMutable( |
michael@0 | 222 | kCFAllocatorDefault, 4, |
michael@0 | 223 | &kCFTypeDictionaryKeyCallBacks, |
michael@0 | 224 | &kCFTypeDictionaryValueCallBacks); |
michael@0 | 225 | if (!props) |
michael@0 | 226 | return nullptr; |
michael@0 | 227 | |
michael@0 | 228 | int32_t bytesPerElem = 4; |
michael@0 | 229 | size_t intScaleFactor = ceil(aContentsScaleFactor); |
michael@0 | 230 | aWidth *= intScaleFactor; |
michael@0 | 231 | aHeight *= intScaleFactor; |
michael@0 | 232 | CFNumberRef cfWidth = ::CFNumberCreate(nullptr, kCFNumberSInt32Type, &aWidth); |
michael@0 | 233 | CFNumberRef cfHeight = ::CFNumberCreate(nullptr, kCFNumberSInt32Type, &aHeight); |
michael@0 | 234 | CFNumberRef cfBytesPerElem = ::CFNumberCreate(nullptr, kCFNumberSInt32Type, &bytesPerElem); |
michael@0 | 235 | ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropWidth, |
michael@0 | 236 | cfWidth); |
michael@0 | 237 | ::CFRelease(cfWidth); |
michael@0 | 238 | ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropHeight, |
michael@0 | 239 | cfHeight); |
michael@0 | 240 | ::CFRelease(cfHeight); |
michael@0 | 241 | ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropBytesPerElem, |
michael@0 | 242 | cfBytesPerElem); |
michael@0 | 243 | ::CFRelease(cfBytesPerElem); |
michael@0 | 244 | ::CFDictionaryAddValue(props, MacIOSurfaceLib::kPropIsGlobal, |
michael@0 | 245 | kCFBooleanTrue); |
michael@0 | 246 | |
michael@0 | 247 | IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceCreate(props); |
michael@0 | 248 | ::CFRelease(props); |
michael@0 | 249 | |
michael@0 | 250 | if (!surfaceRef) |
michael@0 | 251 | return nullptr; |
michael@0 | 252 | |
michael@0 | 253 | RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha); |
michael@0 | 254 | if (!ioSurface) { |
michael@0 | 255 | ::CFRelease(surfaceRef); |
michael@0 | 256 | return nullptr; |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | return ioSurface.forget(); |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | TemporaryRef<MacIOSurface> MacIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID, |
michael@0 | 263 | double aContentsScaleFactor, |
michael@0 | 264 | bool aHasAlpha) { |
michael@0 | 265 | if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0) |
michael@0 | 266 | return nullptr; |
michael@0 | 267 | |
michael@0 | 268 | IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceLookup(aIOSurfaceID); |
michael@0 | 269 | if (!surfaceRef) |
michael@0 | 270 | return nullptr; |
michael@0 | 271 | |
michael@0 | 272 | RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha); |
michael@0 | 273 | if (!ioSurface) { |
michael@0 | 274 | ::CFRelease(surfaceRef); |
michael@0 | 275 | return nullptr; |
michael@0 | 276 | } |
michael@0 | 277 | return ioSurface.forget(); |
michael@0 | 278 | } |
michael@0 | 279 | |
michael@0 | 280 | IOSurfaceID MacIOSurface::GetIOSurfaceID() { |
michael@0 | 281 | return MacIOSurfaceLib::IOSurfaceGetID(mIOSurfacePtr); |
michael@0 | 282 | } |
michael@0 | 283 | |
michael@0 | 284 | void* MacIOSurface::GetBaseAddress() { |
michael@0 | 285 | return MacIOSurfaceLib::IOSurfaceGetBaseAddress(mIOSurfacePtr); |
michael@0 | 286 | } |
michael@0 | 287 | |
michael@0 | 288 | size_t MacIOSurface::GetWidth() { |
michael@0 | 289 | size_t intScaleFactor = ceil(mContentsScaleFactor); |
michael@0 | 290 | return GetDevicePixelWidth() / intScaleFactor; |
michael@0 | 291 | } |
michael@0 | 292 | |
michael@0 | 293 | size_t MacIOSurface::GetHeight() { |
michael@0 | 294 | size_t intScaleFactor = ceil(mContentsScaleFactor); |
michael@0 | 295 | return GetDevicePixelHeight() / intScaleFactor; |
michael@0 | 296 | } |
michael@0 | 297 | |
michael@0 | 298 | size_t MacIOSurface::GetDevicePixelWidth() { |
michael@0 | 299 | return MacIOSurfaceLib::IOSurfaceGetWidth(mIOSurfacePtr); |
michael@0 | 300 | } |
michael@0 | 301 | |
michael@0 | 302 | size_t MacIOSurface::GetDevicePixelHeight() { |
michael@0 | 303 | return MacIOSurfaceLib::IOSurfaceGetHeight(mIOSurfacePtr); |
michael@0 | 304 | } |
michael@0 | 305 | |
michael@0 | 306 | size_t MacIOSurface::GetBytesPerRow() { |
michael@0 | 307 | return MacIOSurfaceLib::IOSurfaceGetBytesPerRow(mIOSurfacePtr); |
michael@0 | 308 | } |
michael@0 | 309 | |
michael@0 | 310 | #define READ_ONLY 0x1 |
michael@0 | 311 | void MacIOSurface::Lock() { |
michael@0 | 312 | MacIOSurfaceLib::IOSurfaceLock(mIOSurfacePtr, READ_ONLY, nullptr); |
michael@0 | 313 | } |
michael@0 | 314 | |
michael@0 | 315 | void MacIOSurface::Unlock() { |
michael@0 | 316 | MacIOSurfaceLib::IOSurfaceUnlock(mIOSurfacePtr, READ_ONLY, nullptr); |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | #include "SourceSurfaceRawData.h" |
michael@0 | 320 | using mozilla::gfx::SourceSurface; |
michael@0 | 321 | using mozilla::gfx::SourceSurfaceRawData; |
michael@0 | 322 | using mozilla::gfx::IntSize; |
michael@0 | 323 | using mozilla::gfx::SurfaceFormat; |
michael@0 | 324 | |
michael@0 | 325 | TemporaryRef<SourceSurface> |
michael@0 | 326 | MacIOSurface::GetAsSurface() { |
michael@0 | 327 | Lock(); |
michael@0 | 328 | size_t bytesPerRow = GetBytesPerRow(); |
michael@0 | 329 | size_t ioWidth = GetDevicePixelWidth(); |
michael@0 | 330 | size_t ioHeight = GetDevicePixelHeight(); |
michael@0 | 331 | |
michael@0 | 332 | unsigned char* ioData = (unsigned char*)GetBaseAddress(); |
michael@0 | 333 | unsigned char* dataCpy = (unsigned char*)malloc(bytesPerRow*ioHeight); |
michael@0 | 334 | for (size_t i = 0; i < ioHeight; i++) { |
michael@0 | 335 | memcpy(dataCpy + i * bytesPerRow, |
michael@0 | 336 | ioData + i * bytesPerRow, ioWidth * 4); |
michael@0 | 337 | } |
michael@0 | 338 | |
michael@0 | 339 | Unlock(); |
michael@0 | 340 | |
michael@0 | 341 | SurfaceFormat format = HasAlpha() ? mozilla::gfx::SurfaceFormat::B8G8R8A8 : |
michael@0 | 342 | mozilla::gfx::SurfaceFormat::B8G8R8X8; |
michael@0 | 343 | |
michael@0 | 344 | RefPtr<SourceSurfaceRawData> surf = new SourceSurfaceRawData(); |
michael@0 | 345 | surf->InitWrappingData(dataCpy, IntSize(ioWidth, ioHeight), bytesPerRow, format, true); |
michael@0 | 346 | |
michael@0 | 347 | return surf.forget(); |
michael@0 | 348 | } |
michael@0 | 349 | |
michael@0 | 350 | CGLError |
michael@0 | 351 | MacIOSurface::CGLTexImageIOSurface2D(CGLContextObj ctx) |
michael@0 | 352 | { |
michael@0 | 353 | return MacIOSurfaceLib::CGLTexImageIOSurface2D(ctx, |
michael@0 | 354 | GL_TEXTURE_RECTANGLE_ARB, |
michael@0 | 355 | HasAlpha() ? GL_RGBA : GL_RGB, |
michael@0 | 356 | GetDevicePixelWidth(), |
michael@0 | 357 | GetDevicePixelHeight(), |
michael@0 | 358 | GL_BGRA, |
michael@0 | 359 | GL_UNSIGNED_INT_8_8_8_8_REV, |
michael@0 | 360 | mIOSurfacePtr, 0); |
michael@0 | 361 | } |
michael@0 | 362 | |
michael@0 | 363 | static |
michael@0 | 364 | CGColorSpaceRef CreateSystemColorSpace() { |
michael@0 | 365 | CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID()); |
michael@0 | 366 | if (!cspace) { |
michael@0 | 367 | cspace = ::CGColorSpaceCreateDeviceRGB(); |
michael@0 | 368 | } |
michael@0 | 369 | return cspace; |
michael@0 | 370 | } |
michael@0 | 371 | |
michael@0 | 372 | CGContextRef MacIOSurface::CreateIOSurfaceContext() { |
michael@0 | 373 | CGColorSpaceRef cspace = CreateSystemColorSpace(); |
michael@0 | 374 | CGContextRef ref = MacIOSurfaceLib::IOSurfaceContextCreate(mIOSurfacePtr, |
michael@0 | 375 | GetDevicePixelWidth(), |
michael@0 | 376 | GetDevicePixelHeight(), |
michael@0 | 377 | 8, 32, cspace, 0x2002); |
michael@0 | 378 | ::CGColorSpaceRelease(cspace); |
michael@0 | 379 | return ref; |
michael@0 | 380 | } |
michael@0 | 381 | |
michael@0 | 382 | CGImageRef MacIOSurface::CreateImageFromIOSurfaceContext(CGContextRef aContext) { |
michael@0 | 383 | if (!MacIOSurfaceLib::isInit()) |
michael@0 | 384 | return nullptr; |
michael@0 | 385 | |
michael@0 | 386 | return MacIOSurfaceLib::IOSurfaceContextCreateImage(aContext); |
michael@0 | 387 | } |
michael@0 | 388 | |
michael@0 | 389 | TemporaryRef<MacIOSurface> MacIOSurface::IOSurfaceContextGetSurface(CGContextRef aContext, |
michael@0 | 390 | double aContentsScaleFactor, |
michael@0 | 391 | bool aHasAlpha) { |
michael@0 | 392 | if (!MacIOSurfaceLib::isInit() || aContentsScaleFactor <= 0) |
michael@0 | 393 | return nullptr; |
michael@0 | 394 | |
michael@0 | 395 | IOSurfacePtr surfaceRef = MacIOSurfaceLib::IOSurfaceContextGetSurface(aContext); |
michael@0 | 396 | if (!surfaceRef) |
michael@0 | 397 | return nullptr; |
michael@0 | 398 | |
michael@0 | 399 | // Retain the IOSurface because MacIOSurface will release it |
michael@0 | 400 | CFRetain(surfaceRef); |
michael@0 | 401 | |
michael@0 | 402 | RefPtr<MacIOSurface> ioSurface = new MacIOSurface(surfaceRef, aContentsScaleFactor, aHasAlpha); |
michael@0 | 403 | if (!ioSurface) { |
michael@0 | 404 | ::CFRelease(surfaceRef); |
michael@0 | 405 | return nullptr; |
michael@0 | 406 | } |
michael@0 | 407 | return ioSurface.forget(); |
michael@0 | 408 | } |
michael@0 | 409 | |
michael@0 | 410 | |
michael@0 | 411 | CGContextType GetContextType(CGContextRef ref) |
michael@0 | 412 | { |
michael@0 | 413 | if (!MacIOSurfaceLib::isInit() || !MacIOSurfaceLib::sCGContextGetTypePtr) |
michael@0 | 414 | return CG_CONTEXT_TYPE_UNKNOWN; |
michael@0 | 415 | |
michael@0 | 416 | unsigned int type = MacIOSurfaceLib::sCGContextGetTypePtr(ref); |
michael@0 | 417 | if (type == CG_CONTEXT_TYPE_BITMAP) { |
michael@0 | 418 | return CG_CONTEXT_TYPE_BITMAP; |
michael@0 | 419 | } else if (type == CG_CONTEXT_TYPE_IOSURFACE) { |
michael@0 | 420 | return CG_CONTEXT_TYPE_IOSURFACE; |
michael@0 | 421 | } else { |
michael@0 | 422 | return CG_CONTEXT_TYPE_UNKNOWN; |
michael@0 | 423 | } |
michael@0 | 424 | } |
michael@0 | 425 | |
michael@0 | 426 |