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