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