1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef EGL_CONFIG_H
17 #define EGL_CONFIG_H
18 
19 #include "EglOsApi.h"
20 #include <EGL/egl.h>
21 #include <EGL/eglext.h>
22 
23 #include <unordered_set>
24 
25 #define MIN_SWAP_INTERVAL 1
26 #define MAX_SWAP_INTERVAL 10
27 
28 #define DEBUG_CHOOSE_CONFIG 0
29 
30 #if DEBUG_CHOOSE_CONFIG
31 #include <stdio.h>
32 #define CHOOSE_CONFIG_DLOG(fmt,...) do { \
33     fprintf(stderr, "chooseconfig: " fmt "\n", ##__VA_ARGS__); \
34 } while(0) \
35 
36 #else
37 #define CHOOSE_CONFIG_DLOG(fmt,...)
38 #endif
39 
40 // A class used to model the content of an EGLConfig object.
41 // This is really a structure with several fields that can be queried
42 // individually with getConfigAttrib(), and compared for sorting according
43 // to the EGLConfig specification.
44 class EglConfig {
45 public:
46     // Return the value of a given attribute, identified by its name |attrib|
47     // (e.g. EGL_CONFIG_ID). On success, return true and sets |*val| to the
48     // attribute value. On failure (unknown |attrib| value), return false.
49     bool getConfAttrib(EGLint attrib, EGLint* val) const;
50     EGLint getConfAttrib(EGLint attrib) const;
51 
52     // Comparison operators used to sort EglConfig instances.
53     bool operator<(const EglConfig& conf) const;
54     bool operator>=(const EglConfig& conf) const;
55     bool operator==(const EglConfig& other) const;
56     // Return a 32-bit hash value, useful for keying on EglConfigs.
57     uint32_t u32hash() const;
58 
59     // Return true iff this instance is compatible with |conf|, i.e. that
60     // they have the same red/green/blue/depth/stencil sizes.
61     bool compatibleWith(const EglConfig& conf)  const; //compatibility
62 
63     // Return true iff this instance matches the minimal requirements of
64     // another EglConfig |dummy|. Any attribute value in |dummy| that isn't
65     // EGL_DONT_CARE will be tested against the corresponding value in the
66     // instance.
67     bool chosen(const EglConfig& dummy) const;
68 
69     // Return the EGL_SURFACE_TYPE value.
surfaceType()70     EGLint surfaceType() const { return m_surface_type;};
71 
72     // Return the EGL_CONFIG_ID value.
id()73     EGLint id() const { return m_config_id; }
setId(EGLint configId)74     void setId(EGLint configId) { m_config_id = configId; }
75 
76     // Return the native pixel format for this config.
nativeFormat()77     EglOS::PixelFormat* nativeFormat() const { return m_nativeFormat; }
78 
79     EglConfig(EGLint red_size,
80               EGLint green_size,
81               EGLint blue_size,
82               EGLint alpha_size,
83               EGLint alpha_mask_size,
84               EGLenum  caveat,
85               EGLint  conformant,
86               EGLint depth_size,
87               EGLint frame_buffer_level,
88               EGLint max_pbuffer_width,
89               EGLint max_pbuffer_height,
90               EGLint max_pbuffer_size,
91               EGLBoolean native_renderable,
92               EGLint renderable_type,
93               EGLint native_visual_id,
94               EGLint native_visual_type,
95               EGLint sample_buffers_num,
96               EGLint samples_per_pixel,
97               EGLint stencil_size,
98               EGLint luminance_size, // We don't really support custom luminance sizes
99               EGLint wanted_buffer_size, // nor buffer sizes (I guess normal CB size + padding),
100                                          // but we still need to properly reject configs that request illegal sizes.
101               EGLint surface_type,
102               EGLenum transparent_type,
103               EGLint trans_red_val,
104               EGLint trans_green_val,
105               EGLint trans_blue_val,
106               EGLBoolean recordable_android,
107               EGLBoolean framebuffer_target_android,
108               EglOS::PixelFormat* frmt);
109 
110     EglConfig(EGLint red_size,
111               EGLint green_size,
112               EGLint blue_size,
113               EGLint alpha_size,
114               EGLint alpha_mask_size,
115               EGLenum  caveat,
116               EGLint depth_size,
117               EGLint frame_buffer_level,
118               EGLint max_pbuffer_width,
119               EGLint max_pbuffer_height,
120               EGLint max_pbuffer_size,
121               EGLBoolean native_renderable,
122               EGLint renderable_type,
123               EGLint native_visual_id,
124               EGLint native_visual_type,
125               EGLint samples_per_pixel,
126               EGLint stencil_size,
127               EGLint surface_type,
128               EGLenum transparent_type,
129               EGLint trans_red_val,
130               EGLint trans_green_val,
131               EGLint trans_blue_val,
132               EGLBoolean recordable_android,
133               EglOS::PixelFormat* frmt);
134 
135     // Copy-constructor.
136     EglConfig(const EglConfig& conf);
137 
138     // A copy-constructor that allows one to override the configuration ID
139     // and red/green/blue/alpha sizes. Note that this is how one creates
140     // an EglConfig instance where nativeId() and id() return different
141     // values (see comment for nativeId()).
142     EglConfig(const EglConfig& conf,
143               EGLint red_size,
144               EGLint green_size,
145               EGLint blue_size,
146               EGLint alpha_size);
147 
148     // Destructor is required to get id of pixel format instance.
~EglConfig()149     ~EglConfig() {
150         delete m_nativeFormat;
151     }
152 
153     // We need to track which EGL config attributes were requested by the user
154     // versus others which are just part of the actual config itself.
155     // addWantedAttrib()/isWantedAttrib() are used in sorting configs
156     // depending on what the user requests.
addWantedAttrib(EGLint wanted)157     void addWantedAttrib(EGLint wanted) {
158         m_wantedAttribs.insert(wanted);
159     }
160 
isWantedAttrib(EGLint wanted)161     bool isWantedAttrib(EGLint wanted) const {
162         return m_wantedAttribs.count(wanted);
163     }
164 
165 private:
166     const EGLint      m_buffer_size;
167     const EGLint      m_red_size;
168     const EGLint      m_green_size;
169     const EGLint      m_blue_size;
170     const EGLint      m_alpha_size;
171     const EGLint      m_alpha_mask_size;
172     const EGLBoolean  m_bind_to_tex_rgb;
173     const EGLBoolean  m_bind_to_tex_rgba;
174     const EGLenum     m_caveat;
175     EGLint            m_config_id = EGL_DONT_CARE;
176     const EGLint      m_frame_buffer_level;
177     const EGLint      m_depth_size;
178     const EGLint      m_max_pbuffer_width;
179     const EGLint      m_max_pbuffer_height;
180     const EGLint      m_max_pbuffer_size;
181     const EGLint      m_max_swap_interval;
182     const EGLint      m_min_swap_interval;
183     const EGLBoolean  m_native_renderable;
184     const EGLint      m_renderable_type;
185     const EGLint      m_native_visual_id;
186     const EGLint      m_native_visual_type;
187     const EGLint      m_sample_buffers_num;
188     const EGLint      m_samples_per_pixel;
189     const EGLint      m_stencil_size;
190     const EGLint      m_luminance_size;
191     const EGLint      m_wanted_buffer_size;
192     const EGLint      m_surface_type;
193     const EGLenum     m_transparent_type;
194     const EGLint      m_trans_red_val;
195     const EGLint      m_trans_green_val;
196     const EGLint      m_trans_blue_val;
197     const EGLBoolean  m_recordable_android;
198     const EGLBoolean  m_framebuffer_target_android;
199     const EGLenum     m_conformant;
200 
201     EglOS::PixelFormat*  m_nativeFormat;
202     const EGLint      m_color_buffer_type;
203 
204     // Track which attribute keys are desired by a user.
205     // This dynamically affects config sorting order.
206     std::unordered_set<EGLint> m_wantedAttribs;
207 };
208 
209 namespace std {
210 template <>
211 struct hash<EglConfig> {
212     std::size_t operator()(const EglConfig& config) const {
213         return (size_t)config.u32hash();
214     }
215 };
216 } // namespace std
217 
218 #endif
219