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