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