• 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 <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 
56     SurfaceID id;
57 
58     EGLLabelKHR label;
59     const egl::Config *config;
60     AttributeMap attributes;
61 
62     bool timestampsEnabled;
63     bool autoRefreshEnabled;
64     SupportedCompositorTiming supportedCompositorTimings;
65     SupportedTimestamps supportedTimestamps;
66     bool directComposition;
67     EGLenum swapBehavior;
68     EGLint swapInterval;
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 postSubBuffer(const gl::Context *context,
88                         EGLint x,
89                         EGLint y,
90                         EGLint width,
91                         EGLint height);
92     Error setPresentationTime(EGLnsecsANDROID time);
93     Error querySurfacePointerANGLE(EGLint attribute, void **value);
94     Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer);
95     Error releaseTexImage(const gl::Context *context, EGLint buffer);
96 
97     Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
98     Error getMscRate(EGLint *numerator, EGLint *denominator);
99 
100     EGLint isPostSubBufferSupported() const;
101 
102     void setRequestedSwapInterval(EGLint interval);
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 getRequestedRenderBuffer() const;
130     EGLenum getSwapBehavior() const;
131     TextureFormat getTextureFormat() const;
132     EGLenum getTextureTarget() const;
133     bool getLargestPbuffer() const;
134     EGLenum getGLColorspace() const;
135     EGLenum getVGAlphaFormat() const;
136     EGLenum getVGColorspace() const;
137     bool getMipmapTexture() const;
138     EGLint getMipmapLevel() const;
139     EGLint getHorizontalResolution() const;
140     EGLint getVerticalResolution() const;
141     EGLenum getMultisampleResolve() const;
142     bool hasProtectedContent() const override;
hasFoveatedRendering()143     bool hasFoveatedRendering() const override { return false; }
getFoveationState()144     const gl::FoveationState *getFoveationState() const override { return nullptr; }
145 
146     // For lock surface buffer
147     EGLint getBitmapPitch() const;
148     EGLint getBitmapOrigin() const;
149     EGLint getRedOffset() const;
150     EGLint getGreenOffset() const;
151     EGLint getBlueOffset() const;
152     EGLint getAlphaOffset() const;
153     EGLint getLuminanceOffset() const;
154     EGLint getBitmapPixelSize() const;
155     EGLAttribKHR getBitmapPointer() const;
156     EGLint getCompressionRate(const egl::Display *display) const;
157     egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes);
158     egl::Error unlockSurfaceKHR(const egl::Display *display);
159 
160     bool isLocked() const;
isCurrentOnAnyContext()161     bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; }
162 
getBoundTexture()163     gl::Texture *getBoundTexture() const { return mTexture; }
164 
165     EGLint isFixedSize() const;
166 
167     // FramebufferAttachmentObject implementation
168     bool isAttachmentSpecified(const gl::ImageIndex &imageIndex) const override;
169     gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override;
170     gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override;
171     GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override;
172     bool isRenderable(const gl::Context *context,
173                       GLenum binding,
174                       const gl::ImageIndex &imageIndex) const override;
175     bool isYUV() const override;
176     bool isExternalImageWithoutIndividualSync() const override;
177     bool hasFrontBufferUsage() const override;
178 
onAttach(const gl::Context * context,rx::UniqueSerial framebufferSerial)179     void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {}
onDetach(const gl::Context * context,rx::UniqueSerial framebufferSerial)180     void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {}
id()181     SurfaceID id() const { return mState.id; }
182     GLuint getId() const override;
183 
getOrientation()184     EGLint getOrientation() const { return mOrientation; }
185 
directComposition()186     bool directComposition() const { return mState.directComposition; }
187 
188     gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override;
189     void setInitState(GLenum binding,
190                       const gl::ImageIndex &imageIndex,
191                       gl::InitState initState) override;
192 
isRobustResourceInitEnabled()193     bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; }
194 
getBindTexImageFormat()195     const gl::Format &getBindTexImageFormat() const { return mColorFormat; }
196 
197     // EGL_ANDROID_get_frame_timestamps entry points
198     void setTimestampsEnabled(bool enabled);
199     bool isTimestampsEnabled() const;
200 
201     // EGL_ANDROID_front_buffer_auto_refresh entry points
202     Error setAutoRefreshEnabled(bool enabled);
203 
204     const SupportedCompositorTiming &getSupportedCompositorTimings() const;
205     Error getCompositorTiming(EGLint numTimestamps,
206                               const EGLint *names,
207                               EGLnsecsANDROID *values) const;
208 
209     Error getNextFrameId(EGLuint64KHR *frameId) const;
210     const SupportedTimestamps &getSupportedTimestamps() const;
211     Error getFrameTimestamps(EGLuint64KHR frameId,
212                              EGLint numTimestamps,
213                              const EGLint *timestamps,
214                              EGLnsecsANDROID *values) const;
215 
216     // Returns the offset into the texture backing the surface if specified via texture offset
217     // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset
218     // otherwise.
getTextureOffset()219     const gl::Offset &getTextureOffset() const { return mTextureOffset; }
220 
221     Error getBufferAge(const gl::Context *context, EGLint *age);
222 
223     Error setRenderBuffer(EGLint renderBuffer);
224     void setRequestedRenderBuffer(EGLint requestedRenderBuffer);
225 
bufferAgeQueriedSinceLastSwap()226     bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; }
227     void setDamageRegion(const EGLint *rects, EGLint n_rects);
isDamageRegionSet()228     bool isDamageRegionSet() const { return mIsDamageRegionSet; }
229 
addRef()230     void addRef() { mRefCount++; }
release()231     void release()
232     {
233         ASSERT(mRefCount > 0);
234         mRefCount--;
235     }
isReferenced()236     bool isReferenced() const { return mRefCount > 0; }
237 
238   protected:
239     Surface(EGLint surfaceType,
240             SurfaceID id,
241             const egl::Config *config,
242             const AttributeMap &attributes,
243             bool forceRobustResourceInit,
244             EGLenum buftype = EGL_NONE);
245     ~Surface() override;
246     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
247 
248     // ANGLE-only method, used internally
249     friend class gl::Texture;
250     Error releaseTexImageFromTexture(const gl::Context *context);
251 
252     SurfaceState mState;
253     rx::SurfaceImpl *mImplementation;
254     int mRefCount;
255     bool mDestroyed;
256 
257     EGLint mType;
258     EGLenum mBuftype;
259 
260     bool mPostSubBufferRequested;
261 
262     bool mLargestPbuffer;
263     EGLenum mGLColorspace;
264     EGLenum mVGAlphaFormat;
265     EGLenum mVGColorspace;
266     bool mMipmapTexture;
267     EGLint mMipmapLevel;
268     EGLint mHorizontalResolution;
269     EGLint mVerticalResolution;
270     EGLenum mMultisampleResolve;
271 
272     bool mFixedSize;
273     size_t mFixedWidth;
274     size_t mFixedHeight;
275 
276     bool mRobustResourceInitialization;
277 
278     TextureFormat mTextureFormat;
279     EGLenum mTextureTarget;
280 
281     EGLint mPixelAspectRatio;        // Display aspect ratio
282     EGLenum mRenderBuffer;           // Render buffer
283     EGLenum mRequestedRenderBuffer;  // Requested render buffer
284 
285     EGLint mRequestedSwapInterval;
286 
287     EGLint mOrientation;
288 
289     // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a
290     // Texture is deleted the Surface is unbound in onDestroy.
291     gl::Texture *mTexture;
292 
293     gl::Format mColorFormat;
294     gl::Format mDSFormat;
295 
296     gl::Offset mTextureOffset;
297 
298     bool mIsCurrentOnAnyContext;  // The surface is current to a context/client API
299     uint8_t *mLockBufferPtr;      // Memory owned by backend.
300     EGLint mLockBufferPitch;
301 
302     bool mBufferAgeQueriedSinceLastSwap;
303     bool mIsDamageRegionSet;
304 
305   private:
306     Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const;
307 
308     Error destroyImpl(const Display *display);
309 
310     void postSwap(const gl::Context *context);
311     Error releaseRef(const Display *display);
312 
313     // ObserverInterface implementation.
314     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
315 
316     Error updatePropertiesOnSwap(const gl::Context *context);
317 
318     gl::InitState mColorInitState;
319     gl::InitState mDepthStencilInitState;
320     angle::ObserverBinding mImplObserverBinding;
321 };
322 
323 class WindowSurface final : public Surface
324 {
325   public:
326     WindowSurface(rx::EGLImplFactory *implFactory,
327                   SurfaceID id,
328                   const Config *config,
329                   EGLNativeWindowType window,
330                   const AttributeMap &attribs,
331                   bool robustResourceInit);
332     ~WindowSurface() override;
333 };
334 
335 class PbufferSurface final : public Surface
336 {
337   public:
338     PbufferSurface(rx::EGLImplFactory *implFactory,
339                    SurfaceID id,
340                    const Config *config,
341                    const AttributeMap &attribs,
342                    bool robustResourceInit);
343     PbufferSurface(rx::EGLImplFactory *implFactory,
344                    SurfaceID id,
345                    const Config *config,
346                    EGLenum buftype,
347                    EGLClientBuffer clientBuffer,
348                    const AttributeMap &attribs,
349                    bool robustResourceInit);
350 
351   protected:
352     ~PbufferSurface() override;
353 };
354 
355 class PixmapSurface final : public Surface
356 {
357   public:
358     PixmapSurface(rx::EGLImplFactory *implFactory,
359                   SurfaceID id,
360                   const Config *config,
361                   NativePixmapType nativePixmap,
362                   const AttributeMap &attribs,
363                   bool robustResourceInit);
364 
365   protected:
366     ~PixmapSurface() override;
367 };
368 
369 class [[nodiscard]] ScopedSurfaceRef
370 {
371   public:
ScopedSurfaceRef(Surface * surface)372     ScopedSurfaceRef(Surface *surface) : mSurface(surface)
373     {
374         if (mSurface)
375         {
376             mSurface->addRef();
377         }
378     }
~ScopedSurfaceRef()379     ~ScopedSurfaceRef()
380     {
381         if (mSurface)
382         {
383             mSurface->release();
384         }
385     }
386 
387   private:
388     Surface *const mSurface;
389 };
390 
391 class SurfaceDeleter final
392 {
393   public:
394     SurfaceDeleter(const Display *display);
395     ~SurfaceDeleter();
396     void operator()(Surface *surface);
397 
398   private:
399     const Display *mDisplay;
400 };
401 
402 using SurfacePointer = std::unique_ptr<Surface, SurfaceDeleter>;
403 
404 }  // namespace egl
405 
406 #endif  // LIBANGLE_SURFACE_H_
407