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