1//
2// Copyright 2002 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Surface.h: Defines the egl::Surface class, representing a drawing surface
8// such as the client area of a window, including any back buffers.
9// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
10
11#ifndef LIBANGLE_SURFACE_H_
12#define LIBANGLE_SURFACE_H_
13
14#include <EGL/egl.h>
15
16#include "common/PackedEnums.h"
17#include "common/angleutils.h"
18#include "libANGLE/AttributeMap.h"
19#include "libANGLE/Debug.h"
20#include "libANGLE/Error.h"
21#include "libANGLE/FramebufferAttachment.h"
22#include "libANGLE/RefCountObject.h"
23#include "libANGLE/formatutils.h"
24#include "libANGLE/renderer/SurfaceImpl.h"
25
26namespace gl
27{
28class Context;
29class Framebuffer;
30class Texture;
31}  // namespace gl
32
33namespace rx
34{
35class EGLImplFactory;
36}
37
38namespace egl
39{
40class Display;
41struct Config;
42
43using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>;
44using SupportedTimestamps       = angle::PackedEnumBitSet<Timestamp>;
45
46struct SurfaceState final : private angle::NonCopyable
47{
48    SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
49    ~SurfaceState();
50
51    bool isRobustResourceInitEnabled() const;
52    bool hasProtectedContent() const;
53    EGLint getPreferredSwapInterval() const;
54
55    EGLLabelKHR label;
56    const egl::Config *config;
57    AttributeMap attributes;
58
59    bool timestampsEnabled;
60    SupportedCompositorTiming supportedCompositorTimings;
61    SupportedTimestamps supportedTimestamps;
62    bool directComposition;
63};
64
65class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
66{
67  public:
68    rx::SurfaceImpl *getImplementation() const { return mImplementation; }
69
70    void setLabel(EGLLabelKHR label) override;
71    EGLLabelKHR getLabel() const override;
72
73    EGLint getType() const;
74
75    Error initialize(const Display *display);
76    Error makeCurrent(const gl::Context *context);
77    Error unMakeCurrent(const gl::Context *context);
78    Error swap(const gl::Context *context);
79    Error swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects);
80    Error swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken);
81    Error postSubBuffer(const gl::Context *context,
82                        EGLint x,
83                        EGLint y,
84                        EGLint width,
85                        EGLint height);
86    Error setPresentationTime(EGLnsecsANDROID time);
87    Error querySurfacePointerANGLE(EGLint attribute, void **value);
88    Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer);
89    Error releaseTexImage(const gl::Context *context, EGLint buffer);
90
91    Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
92    Error getMscRate(EGLint *numerator, EGLint *denominator);
93
94    EGLint isPostSubBufferSupported() const;
95
96    void setSwapInterval(EGLint interval);
97    Error onDestroy(const Display *display);
98
99    void setMipmapLevel(EGLint level);
100    void setMultisampleResolve(EGLenum resolve);
101    void setSwapBehavior(EGLenum behavior);
102
103    void setFixedWidth(EGLint width);
104    void setFixedHeight(EGLint height);
105
106    gl::Framebuffer *createDefaultFramebuffer(const gl::Context *context,
107                                              egl::Surface *readSurface);
108
109    const Config *getConfig() const;
110
111    // width and height can change with client window resizing
112    EGLint getWidth() const;
113    EGLint getHeight() const;
114    // Note: windows cannot be resized on Android.  The approach requires
115    // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR.  However, that is
116    // expensive; and there are troublesome timing issues for other parts of
117    // ANGLE (which cause test failures and crashes).  Therefore, a
118    // special-Android-only path is created just for the querying of EGL_WIDTH
119    // and EGL_HEIGHT.
120    // https://issuetracker.google.com/issues/153329980
121    egl::Error getUserWidth(const egl::Display *display, EGLint *value) const;
122    egl::Error getUserHeight(const egl::Display *display, EGLint *value) const;
123    EGLint getPixelAspectRatio() const;
124    EGLenum getRenderBuffer() const;
125    EGLenum getSwapBehavior() const;
126    TextureFormat getTextureFormat() const;
127    EGLenum getTextureTarget() const;
128    bool getLargestPbuffer() const;
129    EGLenum getGLColorspace() const;
130    EGLenum getVGAlphaFormat() const;
131    EGLenum getVGColorspace() const;
132    bool getMipmapTexture() const;
133    EGLint getMipmapLevel() const;
134    EGLint getHorizontalResolution() const;
135    EGLint getVerticalResolution() const;
136    EGLenum getMultisampleResolve() const;
137    bool hasProtectedContent() const override;
138
139    // For lock surface buffer
140    EGLint getBitmapPitch() const;
141    EGLint getBitmapOrigin() const;
142    EGLint getRedOffset() const;
143    EGLint getGreenOffset() const;
144    EGLint getBlueOffset() const;
145    EGLint getAlphaOffset() const;
146    EGLint getLuminanceOffset() const;
147    EGLint getBitmapPixelSize() const;
148    EGLAttribKHR getBitmapPointer() const;
149    egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes);
150    egl::Error unlockSurfaceKHR(const egl::Display *display);
151
152    bool isLocked() const;
153    bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; }
154
155    gl::Texture *getBoundTexture() const { return mTexture; }
156
157    EGLint isFixedSize() const;
158
159    // FramebufferAttachmentObject implementation
160    gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override;
161    gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override;
162    GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override;
163    bool isRenderable(const gl::Context *context,
164                      GLenum binding,
165                      const gl::ImageIndex &imageIndex) const override;
166    bool isYUV() const override;
167
168    void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override {}
169    void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override {}
170    GLuint getId() const override;
171
172    EGLint getOrientation() const { return mOrientation; }
173
174    bool directComposition() const { return mState.directComposition; }
175
176    gl::InitState initState(const gl::ImageIndex &imageIndex) const override;
177    void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
178
179    bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; }
180
181    const gl::Format &getBindTexImageFormat() const { return mColorFormat; }
182
183    // EGL_ANDROID_get_frame_timestamps entry points
184    void setTimestampsEnabled(bool enabled);
185    bool isTimestampsEnabled() const;
186
187    const SupportedCompositorTiming &getSupportedCompositorTimings() const;
188    Error getCompositorTiming(EGLint numTimestamps,
189                              const EGLint *names,
190                              EGLnsecsANDROID *values) const;
191
192    Error getNextFrameId(EGLuint64KHR *frameId) const;
193    const SupportedTimestamps &getSupportedTimestamps() const;
194    Error getFrameTimestamps(EGLuint64KHR frameId,
195                             EGLint numTimestamps,
196                             const EGLint *timestamps,
197                             EGLnsecsANDROID *values) const;
198
199    // Returns the offset into the texture backing the surface if specified via texture offset
200    // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset
201    // otherwise.
202    const gl::Offset &getTextureOffset() const { return mTextureOffset; }
203
204    Error getBufferAge(const gl::Context *context, EGLint *age) const;
205
206    Error setRenderBuffer(EGLint renderBuffer);
207
208  protected:
209    Surface(EGLint surfaceType,
210            const egl::Config *config,
211            const AttributeMap &attributes,
212            bool forceRobustResourceInit,
213            EGLenum buftype = EGL_NONE);
214    ~Surface() override;
215    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
216
217    gl::Framebuffer *createDefaultFramebuffer(const Display *display);
218
219    // ANGLE-only method, used internally
220    friend class gl::Texture;
221    Error releaseTexImageFromTexture(const gl::Context *context);
222
223    SurfaceState mState;
224    rx::SurfaceImpl *mImplementation;
225    int mRefCount;
226    bool mDestroyed;
227
228    EGLint mType;
229    EGLenum mBuftype;
230
231    bool mPostSubBufferRequested;
232
233    bool mLargestPbuffer;
234    EGLenum mGLColorspace;
235    EGLenum mVGAlphaFormat;
236    EGLenum mVGColorspace;
237    bool mMipmapTexture;
238    EGLint mMipmapLevel;
239    EGLint mHorizontalResolution;
240    EGLint mVerticalResolution;
241    EGLenum mMultisampleResolve;
242
243    bool mFixedSize;
244    size_t mFixedWidth;
245    size_t mFixedHeight;
246
247    bool mRobustResourceInitialization;
248
249    TextureFormat mTextureFormat;
250    EGLenum mTextureTarget;
251
252    EGLint mPixelAspectRatio;  // Display aspect ratio
253    EGLenum mRenderBuffer;     // Render buffer
254    EGLenum mSwapBehavior;     // Buffer swap behavior
255
256    EGLint mOrientation;
257
258    // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a
259    // Texture is deleted the Surface is unbound in onDestroy.
260    gl::Texture *mTexture;
261
262    gl::Format mColorFormat;
263    gl::Format mDSFormat;
264
265    gl::Offset mTextureOffset;
266
267    bool mIsCurrentOnAnyContext;  // The surface is current to a context/client API
268    uint8_t *mLockBufferPtr;      // Memory owned by backend.
269    EGLint mLockBufferPitch;
270
271  private:
272    Error destroyImpl(const Display *display);
273
274    void postSwap(const gl::Context *context);
275    Error releaseRef(const Display *display);
276
277    // ObserverInterface implementation.
278    void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
279
280    gl::InitState mInitState;
281    angle::ObserverBinding mImplObserverBinding;
282};
283
284class WindowSurface final : public Surface
285{
286  public:
287    WindowSurface(rx::EGLImplFactory *implFactory,
288                  const Config *config,
289                  EGLNativeWindowType window,
290                  const AttributeMap &attribs,
291                  bool robustResourceInit);
292    ~WindowSurface() override;
293};
294
295class PbufferSurface final : public Surface
296{
297  public:
298    PbufferSurface(rx::EGLImplFactory *implFactory,
299                   const Config *config,
300                   const AttributeMap &attribs,
301                   bool robustResourceInit);
302    PbufferSurface(rx::EGLImplFactory *implFactory,
303                   const Config *config,
304                   EGLenum buftype,
305                   EGLClientBuffer clientBuffer,
306                   const AttributeMap &attribs,
307                   bool robustResourceInit);
308
309  protected:
310    ~PbufferSurface() override;
311};
312
313class PixmapSurface final : public Surface
314{
315  public:
316    PixmapSurface(rx::EGLImplFactory *implFactory,
317                  const Config *config,
318                  NativePixmapType nativePixmap,
319                  const AttributeMap &attribs,
320                  bool robustResourceInit);
321
322  protected:
323    ~PixmapSurface() override;
324};
325
326class SurfaceDeleter final
327{
328  public:
329    SurfaceDeleter(const Display *display);
330    ~SurfaceDeleter();
331    void operator()(Surface *surface);
332
333  private:
334    const Display *mDisplay;
335};
336
337using SurfacePointer = angle::UniqueObjectPointerBase<Surface, SurfaceDeleter>;
338
339}  // namespace egl
340
341#endif  // LIBANGLE_SURFACE_H_
342