summaryrefslogtreecommitdiffstats
path: root/gfx/2d/MacIOSurface.h
blob: ef176430d12d76b576b1026d7b7c432dc7640ff8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/* -*- 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/. */

#ifndef MacIOSurface_h__
#define MacIOSurface_h__
#ifdef XP_DARWIN
#  include <CoreVideo/CoreVideo.h>
#  include <IOSurface/IOSurface.h>
#  include <QuartzCore/QuartzCore.h>
#  include <dlfcn.h>

#  include "mozilla/gfx/Types.h"
#  include "CFTypeRefPtr.h"

namespace mozilla {
namespace gl {
class GLContext;
}
}  // namespace mozilla

struct _CGLContextObject;

typedef _CGLContextObject* CGLContextObj;
typedef uint32_t IOSurfaceID;

#  ifdef XP_IOS
typedef kern_return_t IOReturn;
typedef int CGLError;
#  endif

#  ifdef XP_MACOSX
#    import <OpenGL/OpenGL.h>
#  else
#    import <OpenGLES/ES2/gl.h>
#  endif

#  include "2D.h"
#  include "mozilla/RefCounted.h"
#  include "mozilla/RefPtr.h"

class MacIOSurface final
    : public mozilla::external::AtomicRefCounted<MacIOSurface> {
 public:
  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurface)
  typedef mozilla::gfx::SourceSurface SourceSurface;
  typedef mozilla::gfx::DrawTarget DrawTarget;
  typedef mozilla::gfx::BackendType BackendType;
  typedef mozilla::gfx::IntSize IntSize;
  typedef mozilla::gfx::YUVColorSpace YUVColorSpace;
  typedef mozilla::gfx::ColorSpace2 ColorSpace2;
  typedef mozilla::gfx::TransferFunction TransferFunction;
  typedef mozilla::gfx::ColorRange ColorRange;
  typedef mozilla::gfx::ColorDepth ColorDepth;

  // The usage count of the IOSurface is increased by 1 during the lifetime
  // of the MacIOSurface instance.
  // MacIOSurface holds a reference to the corresponding IOSurface.

  static already_AddRefed<MacIOSurface> CreateIOSurface(int aWidth, int aHeight,
                                                        bool aHasAlpha = true);
  static already_AddRefed<MacIOSurface> CreateNV12OrP010Surface(
      const IntSize& aYSize, const IntSize& aCbCrSize,
      YUVColorSpace aColorSpace, TransferFunction aTransferFunction,
      ColorRange aColorRange, ColorDepth aColorDepth);
  static already_AddRefed<MacIOSurface> CreateYUV422Surface(
      const IntSize& aSize, YUVColorSpace aColorSpace, ColorRange aColorRange);
  static void ReleaseIOSurface(MacIOSurface* aIOSurface);
  static already_AddRefed<MacIOSurface> LookupSurface(
      IOSurfaceID aSurfaceID, bool aHasAlpha = true,
      mozilla::gfx::YUVColorSpace aColorSpace =
          mozilla::gfx::YUVColorSpace::Identity);

  explicit MacIOSurface(CFTypeRefPtr<IOSurfaceRef> aIOSurfaceRef,
                        bool aHasAlpha = true,
                        mozilla::gfx::YUVColorSpace aColorSpace =
                            mozilla::gfx::YUVColorSpace::Identity);

  ~MacIOSurface();
  IOSurfaceID GetIOSurfaceID() const;
  void* GetBaseAddress() const;
  void* GetBaseAddressOfPlane(size_t planeIndex) const;
  size_t GetPlaneCount() const;
  OSType GetPixelFormat() const;
  // GetWidth() and GetHeight() return values in "display pixels".  A
  // "display pixel" is the smallest fully addressable part of a display.
  // But in HiDPI modes each "display pixel" corresponds to more than one
  // device pixel.  Use GetDevicePixel**() to get device pixels.
  size_t GetWidth(size_t plane = 0) const;
  size_t GetHeight(size_t plane = 0) const;
  IntSize GetSize(size_t plane = 0) const {
    return IntSize(GetWidth(plane), GetHeight(plane));
  }
  size_t GetDevicePixelWidth(size_t plane = 0) const;
  size_t GetDevicePixelHeight(size_t plane = 0) const;
  size_t GetBytesPerRow(size_t plane = 0) const;
  size_t GetAllocSize() const;
  void Lock(bool aReadOnly = true);
  void Unlock(bool aReadOnly = true);
  bool IsLocked() const { return mIsLocked; }
  void IncrementUseCount();
  void DecrementUseCount();
  bool HasAlpha() const { return mHasAlpha; }
  mozilla::gfx::SurfaceFormat GetFormat() const;
  mozilla::gfx::SurfaceFormat GetReadFormat() const;
  mozilla::gfx::ColorDepth GetColorDepth() const;
  // This would be better suited on MacIOSurfaceImage type, however due to the
  // current data structure, this is not possible as only the IOSurfaceRef is
  // being used across.
  void SetYUVColorSpace(YUVColorSpace aColorSpace) {
    mColorSpace = aColorSpace;
  }
  YUVColorSpace GetYUVColorSpace() const { return mColorSpace; }
  bool IsFullRange() const {
    OSType format = GetPixelFormat();
    return (format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ||
            format == kCVPixelFormatType_420YpCbCr10BiPlanarFullRange);
  }
  mozilla::gfx::ColorRange GetColorRange() const {
    if (IsFullRange()) return mozilla::gfx::ColorRange::FULL;
    return mozilla::gfx::ColorRange::LIMITED;
  }

  // We would like to forward declare NSOpenGLContext, but it is an @interface
  // and this file is also used from c++, so we use a void *.
  CGLError CGLTexImageIOSurface2D(
      mozilla::gl::GLContext* aGL, CGLContextObj ctxt, size_t plane,
      mozilla::gfx::SurfaceFormat* aOutReadFormat = nullptr);
  CGLError CGLTexImageIOSurface2D(CGLContextObj ctxt, GLenum target,
                                  GLenum internalFormat, GLsizei width,
                                  GLsizei height, GLenum format, GLenum type,
                                  GLuint plane) const;
  already_AddRefed<SourceSurface> GetAsSurface();

  // Creates a DrawTarget that wraps the data in the IOSurface. Rendering to
  // this DrawTarget directly manipulates the contents of the IOSurface.
  // Only call when the surface is already locked for writing!
  // The returned DrawTarget must only be used while the surface is still
  // locked.
  // Also, only call this if you're reasonably sure that the DrawTarget of the
  // selected backend supports the IOSurface's SurfaceFormat.
  already_AddRefed<DrawTarget> GetAsDrawTargetLocked(BackendType aBackendType);

  static size_t GetMaxWidth();
  static size_t GetMaxHeight();
  CFTypeRefPtr<IOSurfaceRef> GetIOSurfaceRef() { return mIOSurfaceRef; }

  void SetColorSpace(mozilla::gfx::ColorSpace2) const;

  ColorSpace2 mColorPrimaries = ColorSpace2::UNKNOWN;

 private:
  CFTypeRefPtr<IOSurfaceRef> mIOSurfaceRef;
  const bool mHasAlpha;
  YUVColorSpace mColorSpace = YUVColorSpace::Identity;
  bool mIsLocked = false;
};

#endif
#endif