• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 
17 #ifndef ANDROID_SF_HWC2_H
18 #define ANDROID_SF_HWC2_H
19 
20 #define HWC2_INCLUDE_STRINGIFICATION
21 #define HWC2_USE_CPP11
22 #include <hardware/hwcomposer2.h>
23 #undef HWC2_INCLUDE_STRINGIFICATION
24 #undef HWC2_USE_CPP11
25 
26 #include <ui/HdrCapabilities.h>
27 #include <ui/mat4.h>
28 
29 #include <utils/Log.h>
30 #include <utils/StrongPointer.h>
31 #include <utils/Timers.h>
32 
33 #include <functional>
34 #include <string>
35 #include <unordered_map>
36 #include <unordered_set>
37 #include <vector>
38 
39 namespace android {
40     class Fence;
41     class FloatRect;
42     class GraphicBuffer;
43     class Rect;
44     class Region;
45 }
46 
47 namespace HWC2 {
48 
49 class Display;
50 class Layer;
51 
52 typedef std::function<void(std::shared_ptr<Display>, Connection)>
53         HotplugCallback;
54 typedef std::function<void(std::shared_ptr<Display>)> RefreshCallback;
55 typedef std::function<void(std::shared_ptr<Display>, nsecs_t)> VsyncCallback;
56 
57 class Device
58 {
59 public:
60     Device(hwc2_device_t* device);
61     ~Device();
62 
63     friend class HWC2::Display;
64     friend class HWC2::Layer;
65 
66     // Required by HWC2
67 
68     std::string dump() const;
69 
getCapabilities()70     const std::unordered_set<Capability>& getCapabilities() const {
71         return mCapabilities;
72     };
73 
74     uint32_t getMaxVirtualDisplayCount() const;
75     Error createVirtualDisplay(uint32_t width, uint32_t height,
76             android_pixel_format_t* format,
77             std::shared_ptr<Display>* outDisplay);
78 
79     void registerHotplugCallback(HotplugCallback hotplug);
80     void registerRefreshCallback(RefreshCallback refresh);
81     void registerVsyncCallback(VsyncCallback vsync);
82 
83     // For use by callbacks
84 
85     void callHotplug(std::shared_ptr<Display> display, Connection connected);
86     void callRefresh(std::shared_ptr<Display> display);
87     void callVsync(std::shared_ptr<Display> display, nsecs_t timestamp);
88 
89     // Other Device methods
90 
91     // This will create a Display if one is not found, but it will not be marked
92     // as connected. This Display may be null if the display has been torn down
93     // but has not been removed from the map yet.
94     std::shared_ptr<Display> getDisplayById(hwc2_display_t id);
95 
96     bool hasCapability(HWC2::Capability capability) const;
97 
98 private:
99     // Initialization methods
100 
101     template <typename PFN>
loadFunctionPointer(FunctionDescriptor desc,PFN & outPFN)102     [[clang::warn_unused_result]] bool loadFunctionPointer(
103             FunctionDescriptor desc, PFN& outPFN) {
104         auto intDesc = static_cast<int32_t>(desc);
105         auto pfn = mHwcDevice->getFunction(mHwcDevice, intDesc);
106         if (pfn != nullptr) {
107             outPFN = reinterpret_cast<PFN>(pfn);
108             return true;
109         } else {
110             ALOGE("Failed to load function %s", to_string(desc).c_str());
111             return false;
112         }
113     }
114 
115     template <typename PFN, typename HOOK>
registerCallback(Callback callback,HOOK hook)116     void registerCallback(Callback callback, HOOK hook) {
117         static_assert(std::is_same<PFN, HOOK>::value,
118                 "Incompatible function pointer");
119         auto intCallback = static_cast<int32_t>(callback);
120         auto callbackData = static_cast<hwc2_callback_data_t>(this);
121         auto pfn = reinterpret_cast<hwc2_function_pointer_t>(hook);
122         mRegisterCallback(mHwcDevice, intCallback, callbackData, pfn);
123     }
124 
125     void loadCapabilities();
126     void loadFunctionPointers();
127     void registerCallbacks();
128 
129     // For use by Display
130 
131     void destroyVirtualDisplay(hwc2_display_t display);
132 
133     // Member variables
134 
135     hwc2_device_t* mHwcDevice;
136 
137     // Device function pointers
138     HWC2_PFN_CREATE_VIRTUAL_DISPLAY mCreateVirtualDisplay;
139     HWC2_PFN_DESTROY_VIRTUAL_DISPLAY mDestroyVirtualDisplay;
140     HWC2_PFN_DUMP mDump;
141     HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT mGetMaxVirtualDisplayCount;
142     HWC2_PFN_REGISTER_CALLBACK mRegisterCallback;
143 
144     // Display function pointers
145     HWC2_PFN_ACCEPT_DISPLAY_CHANGES mAcceptDisplayChanges;
146     HWC2_PFN_CREATE_LAYER mCreateLayer;
147     HWC2_PFN_DESTROY_LAYER mDestroyLayer;
148     HWC2_PFN_GET_ACTIVE_CONFIG mGetActiveConfig;
149     HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES mGetChangedCompositionTypes;
150     HWC2_PFN_GET_COLOR_MODES mGetColorModes;
151     HWC2_PFN_GET_DISPLAY_ATTRIBUTE mGetDisplayAttribute;
152     HWC2_PFN_GET_DISPLAY_CONFIGS mGetDisplayConfigs;
153     HWC2_PFN_GET_DISPLAY_NAME mGetDisplayName;
154     HWC2_PFN_GET_DISPLAY_REQUESTS mGetDisplayRequests;
155     HWC2_PFN_GET_DISPLAY_TYPE mGetDisplayType;
156     HWC2_PFN_GET_DOZE_SUPPORT mGetDozeSupport;
157     HWC2_PFN_GET_HDR_CAPABILITIES mGetHdrCapabilities;
158     HWC2_PFN_GET_RELEASE_FENCES mGetReleaseFences;
159     HWC2_PFN_PRESENT_DISPLAY mPresentDisplay;
160     HWC2_PFN_SET_ACTIVE_CONFIG mSetActiveConfig;
161     HWC2_PFN_SET_CLIENT_TARGET mSetClientTarget;
162     HWC2_PFN_SET_COLOR_MODE mSetColorMode;
163     HWC2_PFN_SET_COLOR_TRANSFORM mSetColorTransform;
164     HWC2_PFN_SET_OUTPUT_BUFFER mSetOutputBuffer;
165     HWC2_PFN_SET_POWER_MODE mSetPowerMode;
166     HWC2_PFN_SET_VSYNC_ENABLED mSetVsyncEnabled;
167     HWC2_PFN_VALIDATE_DISPLAY mValidateDisplay;
168 
169     // Layer function pointers
170     HWC2_PFN_SET_CURSOR_POSITION mSetCursorPosition;
171     HWC2_PFN_SET_LAYER_BUFFER mSetLayerBuffer;
172     HWC2_PFN_SET_LAYER_SURFACE_DAMAGE mSetLayerSurfaceDamage;
173     HWC2_PFN_SET_LAYER_BLEND_MODE mSetLayerBlendMode;
174     HWC2_PFN_SET_LAYER_COLOR mSetLayerColor;
175     HWC2_PFN_SET_LAYER_COMPOSITION_TYPE mSetLayerCompositionType;
176     HWC2_PFN_SET_LAYER_DATASPACE mSetLayerDataspace;
177     HWC2_PFN_SET_LAYER_DISPLAY_FRAME mSetLayerDisplayFrame;
178     HWC2_PFN_SET_LAYER_PLANE_ALPHA mSetLayerPlaneAlpha;
179     HWC2_PFN_SET_LAYER_SIDEBAND_STREAM mSetLayerSidebandStream;
180     HWC2_PFN_SET_LAYER_SOURCE_CROP mSetLayerSourceCrop;
181     HWC2_PFN_SET_LAYER_TRANSFORM mSetLayerTransform;
182     HWC2_PFN_SET_LAYER_VISIBLE_REGION mSetLayerVisibleRegion;
183     HWC2_PFN_SET_LAYER_Z_ORDER mSetLayerZOrder;
184 
185     std::unordered_set<Capability> mCapabilities;
186     std::unordered_map<hwc2_display_t, std::weak_ptr<Display>> mDisplays;
187 
188     HotplugCallback mHotplug;
189     std::vector<std::pair<std::shared_ptr<Display>, Connection>>
190             mPendingHotplugs;
191     RefreshCallback mRefresh;
192     std::vector<std::shared_ptr<Display>> mPendingRefreshes;
193     VsyncCallback mVsync;
194     std::vector<std::pair<std::shared_ptr<Display>, nsecs_t>> mPendingVsyncs;
195 };
196 
197 class Display : public std::enable_shared_from_this<Display>
198 {
199 public:
200     Display(Device& device, hwc2_display_t id);
201     ~Display();
202 
203     friend class HWC2::Device;
204     friend class HWC2::Layer;
205 
206     class Config
207     {
208     public:
209         class Builder
210         {
211         public:
212             Builder(Display& display, hwc2_config_t id);
213 
build()214             std::shared_ptr<const Config> build() {
215                 return std::const_pointer_cast<const Config>(
216                         std::move(mConfig));
217             }
218 
setWidth(int32_t width)219             Builder& setWidth(int32_t width) {
220                 mConfig->mWidth = width;
221                 return *this;
222             }
setHeight(int32_t height)223             Builder& setHeight(int32_t height) {
224                 mConfig->mHeight = height;
225                 return *this;
226             }
setVsyncPeriod(int32_t vsyncPeriod)227             Builder& setVsyncPeriod(int32_t vsyncPeriod) {
228                 mConfig->mVsyncPeriod = vsyncPeriod;
229                 return *this;
230             }
setDpiX(int32_t dpiX)231             Builder& setDpiX(int32_t dpiX) {
232                 if (dpiX == -1) {
233                     mConfig->mDpiX = getDefaultDensity();
234                 } else {
235                     mConfig->mDpiX = dpiX / 1000.0f;
236                 }
237                 return *this;
238             }
setDpiY(int32_t dpiY)239             Builder& setDpiY(int32_t dpiY) {
240                 if (dpiY == -1) {
241                     mConfig->mDpiY = getDefaultDensity();
242                 } else {
243                     mConfig->mDpiY = dpiY / 1000.0f;
244                 }
245                 return *this;
246             }
247 
248         private:
249             float getDefaultDensity();
250             std::shared_ptr<Config> mConfig;
251         };
252 
getDisplayId()253         hwc2_display_t getDisplayId() const { return mDisplay.getId(); }
getId()254         hwc2_config_t getId() const { return mId; }
255 
getWidth()256         int32_t getWidth() const { return mWidth; }
getHeight()257         int32_t getHeight() const { return mHeight; }
getVsyncPeriod()258         nsecs_t getVsyncPeriod() const { return mVsyncPeriod; }
getDpiX()259         float getDpiX() const { return mDpiX; }
getDpiY()260         float getDpiY() const { return mDpiY; }
261 
262     private:
263         Config(Display& display, hwc2_config_t id);
264 
265         Display& mDisplay;
266         hwc2_config_t mId;
267 
268         int32_t mWidth;
269         int32_t mHeight;
270         nsecs_t mVsyncPeriod;
271         float mDpiX;
272         float mDpiY;
273     };
274 
275     // Required by HWC2
276 
277     [[clang::warn_unused_result]] Error acceptChanges();
278     [[clang::warn_unused_result]] Error createLayer(
279             std::shared_ptr<Layer>* outLayer);
280     [[clang::warn_unused_result]] Error getActiveConfig(
281             std::shared_ptr<const Config>* outConfig) const;
282     [[clang::warn_unused_result]] Error getChangedCompositionTypes(
283             std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes);
284     [[clang::warn_unused_result]] Error getColorModes(
285             std::vector<android_color_mode_t>* outModes) const;
286 
287     // Doesn't call into the HWC2 device, so no errors are possible
288     std::vector<std::shared_ptr<const Config>> getConfigs() const;
289 
290     [[clang::warn_unused_result]] Error getName(std::string* outName) const;
291     [[clang::warn_unused_result]] Error getRequests(
292             DisplayRequest* outDisplayRequests,
293             std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
294                     outLayerRequests);
295     [[clang::warn_unused_result]] Error getType(DisplayType* outType) const;
296     [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const;
297     [[clang::warn_unused_result]] Error getHdrCapabilities(
298             std::unique_ptr<android::HdrCapabilities>* outCapabilities) const;
299     [[clang::warn_unused_result]] Error getReleaseFences(
300             std::unordered_map<std::shared_ptr<Layer>,
301                     android::sp<android::Fence>>* outFences) const;
302     [[clang::warn_unused_result]] Error present(
303             android::sp<android::Fence>* outRetireFence);
304     [[clang::warn_unused_result]] Error setActiveConfig(
305             const std::shared_ptr<const Config>& config);
306     [[clang::warn_unused_result]] Error setClientTarget(
307             buffer_handle_t target,
308             const android::sp<android::Fence>& acquireFence,
309             android_dataspace_t dataspace);
310     [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
311     [[clang::warn_unused_result]] Error setColorTransform(
312             const android::mat4& matrix, android_color_transform_t hint);
313     [[clang::warn_unused_result]] Error setOutputBuffer(
314             const android::sp<android::GraphicBuffer>& buffer,
315             const android::sp<android::Fence>& releaseFence);
316     [[clang::warn_unused_result]] Error setPowerMode(PowerMode mode);
317     [[clang::warn_unused_result]] Error setVsyncEnabled(Vsync enabled);
318     [[clang::warn_unused_result]] Error validate(uint32_t* outNumTypes,
319             uint32_t* outNumRequests);
320 
321     // Other Display methods
322 
getDevice()323     Device& getDevice() const { return mDevice; }
getId()324     hwc2_display_t getId() const { return mId; }
isConnected()325     bool isConnected() const { return mIsConnected; }
326 
327 private:
328     // For use by Device
329 
330     // Virtual displays are always connected
setVirtual()331     void setVirtual() {
332         mIsVirtual = true;
333         mIsConnected = true;
334     }
335 
setConnected(bool connected)336     void setConnected(bool connected) { mIsConnected = connected; }
337     int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
338     void loadConfig(hwc2_config_t configId);
339     void loadConfigs();
340 
341     // For use by Layer
342     void destroyLayer(hwc2_layer_t layerId);
343 
344     // This may fail (and return a null pointer) if no layer with this ID exists
345     // on this display
346     std::shared_ptr<Layer> getLayerById(hwc2_layer_t id) const;
347 
348     // Member variables
349 
350     Device& mDevice;
351     hwc2_display_t mId;
352     bool mIsConnected;
353     bool mIsVirtual;
354     std::unordered_map<hwc2_layer_t, std::weak_ptr<Layer>> mLayers;
355     std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
356 };
357 
358 class Layer
359 {
360 public:
361     Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id);
362     ~Layer();
363 
isAbandoned()364     bool isAbandoned() const { return mDisplay.expired(); }
getId()365     hwc2_layer_t getId() const { return mId; }
366 
367     [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
368     [[clang::warn_unused_result]] Error setBuffer(buffer_handle_t buffer,
369             const android::sp<android::Fence>& acquireFence);
370     [[clang::warn_unused_result]] Error setSurfaceDamage(
371             const android::Region& damage);
372 
373     [[clang::warn_unused_result]] Error setBlendMode(BlendMode mode);
374     [[clang::warn_unused_result]] Error setColor(hwc_color_t color);
375     [[clang::warn_unused_result]] Error setCompositionType(Composition type);
376     [[clang::warn_unused_result]] Error setDataspace(
377             android_dataspace_t dataspace);
378     [[clang::warn_unused_result]] Error setDisplayFrame(
379             const android::Rect& frame);
380     [[clang::warn_unused_result]] Error setPlaneAlpha(float alpha);
381     [[clang::warn_unused_result]] Error setSidebandStream(
382             const native_handle_t* stream);
383     [[clang::warn_unused_result]] Error setSourceCrop(
384             const android::FloatRect& crop);
385     [[clang::warn_unused_result]] Error setTransform(Transform transform);
386     [[clang::warn_unused_result]] Error setVisibleRegion(
387             const android::Region& region);
388     [[clang::warn_unused_result]] Error setZOrder(uint32_t z);
389 
390 private:
391     std::weak_ptr<Display> mDisplay;
392     hwc2_display_t mDisplayId;
393     Device& mDevice;
394     hwc2_layer_t mId;
395 };
396 
397 } // namespace HWC2
398 
399 #endif // ANDROID_SF_HWC2_H
400