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