1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MacIOSurface_h__ 8 #define MacIOSurface_h__ 9 #ifdef XP_DARWIN 10 # include <CoreVideo/CoreVideo.h> 11 # include <IOSurface/IOSurface.h> 12 # include <QuartzCore/QuartzCore.h> 13 # include <dlfcn.h> 14 15 # include "mozilla/gfx/Types.h" 16 # include "CFTypeRefPtr.h" 17 18 namespace mozilla { 19 namespace gl { 20 class GLContext; 21 } 22 } // namespace mozilla 23 24 struct _CGLContextObject; 25 26 typedef _CGLContextObject* CGLContextObj; 27 typedef uint32_t IOSurfaceID; 28 29 # ifdef XP_IOS 30 typedef kern_return_t IOReturn; 31 typedef int CGLError; 32 # endif 33 34 # ifdef XP_MACOSX 35 # import <OpenGL/OpenGL.h> 36 # else 37 # import <OpenGLES/ES2/gl.h> 38 # endif 39 40 # include "2D.h" 41 # include "mozilla/RefCounted.h" 42 # include "mozilla/RefPtr.h" 43 44 class MacIOSurface final 45 : public mozilla::external::AtomicRefCounted<MacIOSurface> { 46 public: 47 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurface) 48 typedef mozilla::gfx::SourceSurface SourceSurface; 49 typedef mozilla::gfx::DrawTarget DrawTarget; 50 typedef mozilla::gfx::BackendType BackendType; 51 typedef mozilla::gfx::IntSize IntSize; 52 typedef mozilla::gfx::YUVColorSpace YUVColorSpace; 53 typedef mozilla::gfx::ColorRange ColorRange; 54 55 // The usage count of the IOSurface is increased by 1 during the lifetime 56 // of the MacIOSurface instance. 57 // MacIOSurface holds a reference to the corresponding IOSurface. 58 59 static already_AddRefed<MacIOSurface> CreateIOSurface(int aWidth, int aHeight, 60 bool aHasAlpha = true); 61 static already_AddRefed<MacIOSurface> CreateNV12Surface( 62 const IntSize& aYSize, const IntSize& aCbCrSize, 63 YUVColorSpace aColorSpace, ColorRange aColorRange); 64 static already_AddRefed<MacIOSurface> CreateYUV422Surface( 65 const IntSize& aSize, YUVColorSpace aColorSpace, ColorRange aColorRange); 66 static void ReleaseIOSurface(MacIOSurface* aIOSurface); 67 static already_AddRefed<MacIOSurface> LookupSurface( 68 IOSurfaceID aSurfaceID, bool aHasAlpha = true, 69 mozilla::gfx::YUVColorSpace aColorSpace = 70 mozilla::gfx::YUVColorSpace::Identity); 71 72 explicit MacIOSurface(CFTypeRefPtr<IOSurfaceRef> aIOSurfaceRef, 73 bool aHasAlpha = true, 74 mozilla::gfx::YUVColorSpace aColorSpace = 75 mozilla::gfx::YUVColorSpace::Identity); 76 77 ~MacIOSurface(); 78 IOSurfaceID GetIOSurfaceID() const; 79 void* GetBaseAddress() const; 80 void* GetBaseAddressOfPlane(size_t planeIndex) const; 81 size_t GetPlaneCount() const; 82 OSType GetPixelFormat() const; 83 // GetWidth() and GetHeight() return values in "display pixels". A 84 // "display pixel" is the smallest fully addressable part of a display. 85 // But in HiDPI modes each "display pixel" corresponds to more than one 86 // device pixel. Use GetDevicePixel**() to get device pixels. 87 size_t GetWidth(size_t plane = 0) const; 88 size_t GetHeight(size_t plane = 0) const; 89 IntSize GetSize(size_t plane = 0) const { 90 return IntSize(GetWidth(plane), GetHeight(plane)); 91 } 92 size_t GetDevicePixelWidth(size_t plane = 0) const; 93 size_t GetDevicePixelHeight(size_t plane = 0) const; 94 size_t GetBytesPerRow(size_t plane = 0) const; 95 size_t GetAllocSize() const; 96 void Lock(bool aReadOnly = true); 97 void Unlock(bool aReadOnly = true); IsLocked()98 bool IsLocked() const { return mIsLocked; } 99 void IncrementUseCount(); 100 void DecrementUseCount(); HasAlpha()101 bool HasAlpha() const { return mHasAlpha; } 102 mozilla::gfx::SurfaceFormat GetFormat() const; 103 mozilla::gfx::SurfaceFormat GetReadFormat() const; 104 // This would be better suited on MacIOSurfaceImage type, however due to the 105 // current data structure, this is not possible as only the IOSurfaceRef is 106 // being used across. SetYUVColorSpace(YUVColorSpace aColorSpace)107 void SetYUVColorSpace(YUVColorSpace aColorSpace) { 108 mColorSpace = aColorSpace; 109 } GetYUVColorSpace()110 YUVColorSpace GetYUVColorSpace() const { return mColorSpace; } IsFullRange()111 bool IsFullRange() const { 112 return GetPixelFormat() == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange; 113 } GetColorRange()114 mozilla::gfx::ColorRange GetColorRange() const { 115 if (IsFullRange()) return mozilla::gfx::ColorRange::FULL; 116 return mozilla::gfx::ColorRange::LIMITED; 117 } 118 119 // We would like to forward declare NSOpenGLContext, but it is an @interface 120 // and this file is also used from c++, so we use a void *. 121 CGLError CGLTexImageIOSurface2D( 122 mozilla::gl::GLContext* aGL, CGLContextObj ctxt, size_t plane, 123 mozilla::gfx::SurfaceFormat* aOutReadFormat = nullptr); 124 CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt, GLenum target, 125 GLenum internalFormat, GLsizei width, 126 GLsizei height, GLenum format, GLenum type, 127 GLuint plane) const; 128 already_AddRefed<SourceSurface> GetAsSurface(); 129 130 // Creates a DrawTarget that wraps the data in the IOSurface. Rendering to 131 // this DrawTarget directly manipulates the contents of the IOSurface. 132 // Only call when the surface is already locked for writing! 133 // The returned DrawTarget must only be used while the surface is still 134 // locked. 135 // Also, only call this if you're reasonably sure that the DrawTarget of the 136 // selected backend supports the IOSurface's SurfaceFormat. 137 already_AddRefed<DrawTarget> GetAsDrawTargetLocked(BackendType aBackendType); 138 139 static size_t GetMaxWidth(); 140 static size_t GetMaxHeight(); GetIOSurfaceRef()141 CFTypeRefPtr<IOSurfaceRef> GetIOSurfaceRef() { return mIOSurfaceRef; } 142 143 private: 144 CFTypeRefPtr<IOSurfaceRef> mIOSurfaceRef; 145 const bool mHasAlpha; 146 YUVColorSpace mColorSpace = YUVColorSpace::Identity; 147 bool mIsLocked = false; 148 }; 149 150 #endif 151 #endif 152