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