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