1 /* 2 * Copyright 2018 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_HW_EMU_HWC2_H 18 #define ANDROID_HW_EMU_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 #include <utils/Thread.h> 26 27 #include <android-base/unique_fd.h> 28 #include <atomic> 29 #include <map> 30 #include <memory> 31 #include <mutex> 32 #include <numeric> 33 #include <sstream> 34 #include <vector> 35 #include <unordered_set> 36 #include <unordered_map> 37 #include <set> 38 39 #include <cutils/native_handle.h> 40 41 #include "HostConnection.h" 42 43 namespace android { 44 45 class EmuHWC2 : public hwc2_device_t { 46 public: 47 EmuHWC2(); 48 int populatePrimary(); 49 int populateSecondaryDisplays(); 50 51 private: getHWC2(hwc2_device_t * device)52 static inline EmuHWC2* getHWC2(hwc2_device_t* device) { 53 return static_cast<EmuHWC2*>(device); 54 } 55 closeHook(hw_device_t * device)56 static int closeHook(hw_device_t* device) { 57 EmuHWC2 *ctx = reinterpret_cast<EmuHWC2*>(device); 58 delete ctx; 59 return 0; 60 } 61 62 // getCapabilities 63 void doGetCapabilities(uint32_t* outCount, int32_t* outCapabilities); getCapabilitiesHook(hwc2_device_t * device,uint32_t * outCount,int32_t * outCapabilities)64 static void getCapabilitiesHook(hwc2_device_t* device, uint32_t* outCount, 65 int32_t* outCapabilities) { 66 getHWC2(device)->doGetCapabilities(outCount, outCapabilities); 67 } 68 69 // getFunction 70 hwc2_function_pointer_t doGetFunction(HWC2::FunctionDescriptor descriptor); getFunctionHook(hwc2_device_t * device,int32_t desc)71 static hwc2_function_pointer_t getFunctionHook(hwc2_device_t* device, 72 int32_t desc) { 73 auto descriptor = static_cast<HWC2::FunctionDescriptor>(desc); 74 return getHWC2(device)->doGetFunction(descriptor); 75 } 76 77 // Device functions 78 HWC2::Error createVirtualDisplay(uint32_t width, uint32_t height, 79 int32_t* format, hwc2_display_t* outDisplay); createVirtualDisplayHook(hwc2_device_t * device,uint32_t width,uint32_t height,int32_t * format,hwc2_display_t * outDisplay)80 static int32_t createVirtualDisplayHook(hwc2_device_t* device, 81 uint32_t width, uint32_t height, int32_t* format, 82 hwc2_display_t* outDisplay) { 83 auto error = getHWC2(device)->createVirtualDisplay(width, height, 84 format, outDisplay); 85 return static_cast<int32_t>(error); 86 } 87 88 HWC2::Error destroyVirtualDisplay(hwc2_display_t display); destroyVirtualDisplayHook(hwc2_device_t * device,hwc2_display_t display)89 static int32_t destroyVirtualDisplayHook(hwc2_device_t* device, 90 hwc2_display_t display) { 91 auto error = getHWC2(device)->destroyVirtualDisplay(display); 92 return static_cast<int32_t>(error); 93 } 94 95 std::string mDumpString; 96 void dump(uint32_t* outSize, char* outBuffer); dumpHook(hwc2_device_t * device,uint32_t * outSize,char * outBuffer)97 static void dumpHook(hwc2_device_t* device, uint32_t* outSize, 98 char* outBuffer) { 99 getHWC2(device)->dump(outSize, outBuffer); 100 } 101 102 uint32_t getMaxVirtualDisplayCount(); getMaxVirtualDisplayCountHook(hwc2_device_t * device)103 static uint32_t getMaxVirtualDisplayCountHook(hwc2_device_t* device) { 104 return getHWC2(device)->getMaxVirtualDisplayCount(); 105 } 106 107 HWC2::Error registerCallback(HWC2::Callback descriptor, 108 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer); registerCallbackHook(hwc2_device_t * device,int32_t intDesc,hwc2_callback_data_t callbackData,hwc2_function_pointer_t pointer)109 static int32_t registerCallbackHook(hwc2_device_t* device, 110 int32_t intDesc, hwc2_callback_data_t callbackData, 111 hwc2_function_pointer_t pointer) { 112 auto descriptor = static_cast<HWC2::Callback>(intDesc); 113 auto error = getHWC2(device)->registerCallback(descriptor, 114 callbackData, pointer); 115 return static_cast<int32_t>(error); 116 } 117 118 class Layer; 119 class SortLayersByZ { 120 public: 121 bool operator()(const std::shared_ptr<Layer>& lhs, 122 const std::shared_ptr<Layer>& rhs) const; 123 }; 124 125 // SurfaceFlinger sets the ColorBuffer and its Fence handler for each 126 // layer. This class is a container for these two. 127 class FencedBuffer { 128 public: FencedBuffer()129 FencedBuffer() : mBuffer(nullptr) {} 130 setBuffer(buffer_handle_t buffer)131 void setBuffer(buffer_handle_t buffer) { mBuffer = buffer; } setFence(int fenceFd)132 void setFence(int fenceFd) { 133 mFence = std::make_shared<base::unique_fd>(fenceFd); 134 } 135 getBuffer()136 buffer_handle_t getBuffer() const { return mBuffer; } getFence()137 int getFence() const { return mFence ? dup(mFence->get()) : -1; } 138 139 private: 140 buffer_handle_t mBuffer; 141 std::shared_ptr<base::unique_fd> mFence; 142 }; 143 144 typedef struct compose_layer { 145 uint32_t cbHandle; 146 hwc2_composition_t composeMode; 147 hwc_rect_t displayFrame; 148 hwc_frect_t crop; 149 int32_t blendMode; 150 float alpha; 151 hwc_color_t color; 152 hwc_transform_t transform; 153 } ComposeLayer; 154 typedef struct compose_device { 155 uint32_t version; 156 uint32_t targetHandle; 157 uint32_t numLayers; 158 struct compose_layer layer[0]; 159 } ComposeDevice; 160 typedef struct compose_device_v2 { 161 uint32_t version; 162 uint32_t displayId; 163 uint32_t targetHandle; 164 uint32_t numLayers; 165 struct compose_layer layer[0]; 166 } ComposeDevice_v2; 167 168 class ComposeMsg { 169 public: 170 ComposeMsg(uint32_t layerCnt = 0) : 171 mData(sizeof(ComposeDevice) + layerCnt * sizeof(ComposeLayer)) 172 { 173 mComposeDevice = reinterpret_cast<ComposeDevice*>(mData.data()); 174 mLayerCnt = layerCnt; 175 } 176 get()177 ComposeDevice* get() { return mComposeDevice; } 178 getLayerCnt()179 uint32_t getLayerCnt() { return mLayerCnt; } 180 181 private: 182 std::vector<uint8_t> mData; 183 uint32_t mLayerCnt; 184 ComposeDevice* mComposeDevice; 185 }; 186 187 class ComposeMsg_v2 { 188 public: 189 ComposeMsg_v2(uint32_t layerCnt = 0) : 190 mData(sizeof(ComposeDevice_v2) + layerCnt * sizeof(ComposeLayer)) 191 { 192 mComposeDevice = reinterpret_cast<ComposeDevice_v2*>(mData.data()); 193 mLayerCnt = layerCnt; 194 } 195 get()196 ComposeDevice_v2* get() { return mComposeDevice; } 197 getLayerCnt()198 uint32_t getLayerCnt() { return mLayerCnt; } 199 200 private: 201 std::vector<uint8_t> mData; 202 uint32_t mLayerCnt; 203 ComposeDevice_v2* mComposeDevice; 204 }; 205 206 class Display { 207 public: 208 Display(EmuHWC2& device, HWC2::DisplayType type, int width, int height); 209 ~Display(); getId()210 hwc2_display_t getId() const {return mId;} 211 212 // HWC2 Display functions 213 HWC2::Error acceptChanges(); 214 HWC2::Error createLayer(hwc2_layer_t* outLayerId); 215 HWC2::Error destroyLayer(hwc2_layer_t layerId); 216 HWC2::Error getActiveConfig(hwc2_config_t* outConfigId); 217 HWC2::Error getDisplayAttribute(hwc2_config_t configId, 218 int32_t attribute, int32_t* outValue); 219 HWC2::Error getChangedCompositionTypes(uint32_t* outNumElements, 220 hwc2_layer_t* outLayers, int32_t* outTypes); 221 HWC2::Error getColorModes(uint32_t* outNumModes, int32_t* outModes); 222 HWC2::Error getConfigs(uint32_t* outNumConfigs, 223 hwc2_config_t* outConfigIds); 224 HWC2::Error getDozeSupport(int32_t* outSupport); 225 HWC2::Error getHdrCapabilities(uint32_t* outNumTypes, 226 int32_t* outTypes, float* outMaxLuminance, 227 float* outMaxAverageLuminance, float* outMinLuminance); 228 HWC2::Error getName(uint32_t* outSize, char* outName); 229 HWC2::Error getReleaseFences(uint32_t* outNumElements, 230 hwc2_layer_t* outLayers, int32_t* outFences); 231 HWC2::Error getRequests(int32_t* outDisplayRequests, 232 uint32_t* outNumElements, hwc2_layer_t* outLayers, 233 int32_t* outLayerRequests); 234 HWC2::Error getType(int32_t* outType); 235 HWC2::Error present(int32_t* outRetireFence); 236 HWC2::Error setActiveConfig(hwc2_config_t configId); 237 HWC2::Error setClientTarget(buffer_handle_t target, 238 int32_t acquireFence, int32_t dataspace, 239 hwc_region_t damage); 240 HWC2::Error setColorMode(int32_t mode); 241 HWC2::Error setColorTransform(const float* matrix, 242 int32_t hint); 243 HWC2::Error setOutputBuffer(buffer_handle_t buffer, 244 int32_t releaseFence); 245 HWC2::Error setPowerMode(int32_t mode); 246 HWC2::Error setVsyncEnabled(int32_t enabled); 247 HWC2::Error validate(uint32_t* outNumTypes, 248 uint32_t* outNumRequests); 249 HWC2::Error updateLayerZ(hwc2_layer_t layerId, uint32_t z); 250 HWC2::Error getClientTargetSupport(uint32_t width, uint32_t height, 251 int32_t format, int32_t dataspace); 252 // 2.3 required functions 253 HWC2::Error getDisplayIdentificationData(uint8_t* outPort, 254 uint32_t* outDataSize, uint8_t* outData); 255 HWC2::Error getDisplayCapabilities(uint32_t* outNumCapabilities, 256 uint32_t* outCapabilities); 257 HWC2::Error getDisplayBrightnessSupport(bool *out_support); 258 HWC2::Error setDisplayBrightness(float brightness); 259 260 // Read configs from PRIMARY Display 261 int populatePrimaryConfigs(int width, int height, int dpiX, int dpiY); 262 HWC2::Error populateSecondaryConfigs(uint32_t width, uint32_t height, 263 uint32_t dpi, uint32_t idx); 264 265 private: 266 void post(HostConnection *hostCon, ExtendedRCEncoderContext *rcEnc, 267 buffer_handle_t h); 268 269 class Config { 270 public: Config(Display & display)271 Config(Display& display) 272 : mDisplay(display), 273 mId(0), 274 mAttributes() {} 275 isOnDisplay(const Display & display)276 bool isOnDisplay(const Display& display) const { 277 return display.getId() == mDisplay.getId(); 278 } 279 void setAttribute(HWC2::Attribute attribute, int32_t value); 280 int32_t getAttribute(HWC2::Attribute attribute) const; setId(hwc2_config_t id)281 void setId(hwc2_config_t id) {mId = id; } getId()282 hwc2_config_t getId() const {return mId; } 283 std::string toString() const; 284 285 private: 286 Display& mDisplay; 287 hwc2_config_t mId; 288 std::unordered_map<HWC2::Attribute, int32_t> mAttributes; 289 }; 290 291 // Stores changes requested from the device upon calling prepare(). 292 // Handles change request to: 293 // - Layer composition type. 294 // - Layer hints. 295 class Changes { 296 public: getNumTypes()297 uint32_t getNumTypes() const { 298 return static_cast<uint32_t>(mTypeChanges.size()); 299 } 300 getNumLayerRequests()301 uint32_t getNumLayerRequests() const { 302 return static_cast<uint32_t>(mLayerRequests.size()); 303 } 304 305 const std::unordered_map<hwc2_layer_t, HWC2::Composition>& getTypeChanges()306 getTypeChanges() const { 307 return mTypeChanges; 308 } 309 310 const std::unordered_map<hwc2_layer_t, HWC2::LayerRequest>& getLayerRequests()311 getLayerRequests() const { 312 return mLayerRequests; 313 } 314 addTypeChange(hwc2_layer_t layerId,HWC2::Composition type)315 void addTypeChange(hwc2_layer_t layerId, 316 HWC2::Composition type) { 317 mTypeChanges.insert({layerId, type}); 318 } 319 clearTypeChanges()320 void clearTypeChanges() { mTypeChanges.clear(); } 321 addLayerRequest(hwc2_layer_t layerId,HWC2::LayerRequest request)322 void addLayerRequest(hwc2_layer_t layerId, 323 HWC2::LayerRequest request) { 324 mLayerRequests.insert({layerId, request}); 325 } 326 327 private: 328 std::unordered_map<hwc2_layer_t, HWC2::Composition> 329 mTypeChanges; 330 std::unordered_map<hwc2_layer_t, HWC2::LayerRequest> 331 mLayerRequests; 332 }; 333 334 // Generate sw vsync signal 335 class VsyncThread : public Thread { 336 public: VsyncThread(Display & display)337 VsyncThread(Display& display) 338 : mDisplay(display) {} ~VsyncThread()339 virtual ~VsyncThread() {} 340 private: 341 Display& mDisplay; 342 bool threadLoop() final; 343 }; 344 345 private: 346 EmuHWC2& mDevice; 347 // Display ID generator. 348 static std::atomic<hwc2_display_t> sNextId; 349 static const uint32_t hostDisplayIdStart = 6; 350 const hwc2_display_t mId; 351 // emulator side displayId 352 uint32_t mHostDisplayId; 353 std::string mName; 354 HWC2::DisplayType mType; 355 HWC2::PowerMode mPowerMode; 356 HWC2::Vsync mVsyncEnabled; 357 uint32_t mVsyncPeriod; 358 VsyncThread mVsyncThread; 359 FencedBuffer mClientTarget; 360 // Will only be non-null after the Display has been validated and 361 // before it has been presented 362 std::unique_ptr<Changes> mChanges; 363 // All layers this Display is aware of. 364 std::multiset<std::shared_ptr<Layer>, SortLayersByZ> mLayers; 365 std::vector<hwc2_display_t> mReleaseLayerIds; 366 std::vector<int32_t> mReleaseFences; 367 std::vector<std::shared_ptr<Config>> mConfigs; 368 std::shared_ptr<const Config> mActiveConfig; 369 std::set<android_color_mode_t> mColorModes; 370 android_color_mode_t mActiveColorMode; 371 bool mSetColorTransform; 372 // The state of this display should only be modified from 373 // SurfaceFlinger's main loop, with the exception of when dump is 374 // called. To prevent a bad state from crashing us during a dump 375 // call, all public calls into Display must acquire this mutex. 376 mutable std::mutex mStateMutex; 377 std::unique_ptr<ComposeMsg> mComposeMsg; 378 std::unique_ptr<ComposeMsg_v2> mComposeMsg_v2; 379 int mSyncDeviceFd; 380 const native_handle_t* mTargetCb; 381 }; 382 383 template<typename MF, MF memFunc, typename ...Args> displayHook(hwc2_device_t * device,hwc2_display_t displayId,Args...args)384 static int32_t displayHook(hwc2_device_t* device, hwc2_display_t displayId, 385 Args... args) { 386 auto display = getHWC2(device)->getDisplay(displayId); 387 if (!display) { 388 return static_cast<int32_t>(HWC2::Error::BadDisplay); 389 } 390 auto error = ((*display).*memFunc)(std::forward<Args>(args)...); 391 return static_cast<int32_t>(error); 392 } 393 394 class Layer { 395 public: 396 explicit Layer(Display& display); getDisplay()397 Display& getDisplay() const {return mDisplay;} getId()398 hwc2_layer_t getId() const {return mId;} 399 bool operator==(const Layer& other) { return mId == other.mId; } 400 bool operator!=(const Layer& other) { return !(*this == other); } 401 402 // HWC2 Layer functions 403 HWC2::Error setBuffer(buffer_handle_t buffer, int32_t acquireFence); 404 HWC2::Error setCursorPosition(int32_t x, int32_t y); 405 HWC2::Error setSurfaceDamage(hwc_region_t damage); 406 407 // HWC2 Layer state functions 408 HWC2::Error setBlendMode(int32_t mode); 409 HWC2::Error setColor(hwc_color_t color); 410 HWC2::Error setCompositionType(int32_t type); 411 HWC2::Error setDataspace(int32_t dataspace); 412 HWC2::Error setDisplayFrame(hwc_rect_t frame); 413 HWC2::Error setPlaneAlpha(float alpha); 414 HWC2::Error setSidebandStream(const native_handle_t* stream); 415 HWC2::Error setSourceCrop(hwc_frect_t crop); 416 HWC2::Error setTransform(int32_t transform); 417 HWC2::Error setVisibleRegion(hwc_region_t visible); 418 HWC2::Error setZ(uint32_t z); 419 getCompositionType()420 HWC2::Composition getCompositionType() const { 421 return mCompositionType; 422 } getColor()423 hwc_color_t getColor() {return mColor; } getZ()424 uint32_t getZ() {return mZ; } getNumVisibleRegions()425 std::size_t getNumVisibleRegions() {return mVisibleRegion.size(); } getLayerBuffer()426 FencedBuffer& getLayerBuffer() {return mBuffer; } getBlendMode()427 int32_t getBlendMode() {return (int32_t)mBlendMode; } getPlaneAlpha()428 float getPlaneAlpha() {return mPlaneAlpha; } getSourceCrop()429 hwc_frect_t getSourceCrop() {return mSourceCrop; } getDisplayFrame()430 hwc_rect_t getDisplayFrame() {return mDisplayFrame; } getTransform()431 hwc_transform_t getTransform() {return (hwc_transform_t)mTransform; } 432 private: 433 static std::atomic<hwc2_layer_t> sNextId; 434 const hwc2_layer_t mId; 435 Display& mDisplay; 436 FencedBuffer mBuffer; 437 std::vector<hwc_rect_t> mSurfaceDamage; 438 439 HWC2::BlendMode mBlendMode; 440 hwc_color_t mColor; 441 HWC2::Composition mCompositionType; 442 hwc_rect_t mDisplayFrame; 443 float mPlaneAlpha; 444 const native_handle_t* mSidebandStream; 445 hwc_frect_t mSourceCrop; 446 HWC2::Transform mTransform; 447 std::vector<hwc_rect_t> mVisibleRegion; 448 uint32_t mZ; 449 }; 450 451 template <typename MF, MF memFunc, typename ...Args> layerHook(hwc2_device_t * device,hwc2_display_t displayId,hwc2_layer_t layerId,Args...args)452 static int32_t layerHook(hwc2_device_t* device, hwc2_display_t displayId, 453 hwc2_layer_t layerId, Args... args) { 454 auto result = getHWC2(device)->getLayer(displayId, layerId); 455 auto error = std::get<HWC2::Error>(result); 456 if (error == HWC2::Error::None) { 457 auto layer = std::get<Layer*>(result); 458 error = ((*layer).*memFunc)(std::forward<Args>(args)...); 459 } 460 return static_cast<int32_t>(error); 461 } 462 463 // helpers 464 void populateCapabilities(); 465 Display* getDisplay(hwc2_display_t id); 466 std::tuple<Layer*, HWC2::Error> getLayer(hwc2_display_t displayId, 467 hwc2_layer_t layerId); 468 469 HWC2::Error initDisplayParameters(); 470 const native_handle_t* allocateDisplayColorBuffer(int width, int height); 471 void freeDisplayColorBuffer(const native_handle_t* h); 472 473 std::unordered_set<HWC2::Capability> mCapabilities; 474 475 // These are potentially accessed from multiple threads, and are protected 476 // by this mutex. 477 std::mutex mStateMutex; 478 479 struct CallbackInfo { 480 hwc2_callback_data_t data; 481 hwc2_function_pointer_t pointer; 482 }; 483 std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks; 484 485 // use map so displays can be pluged in by order of ID, 0, 1, 2, 3, etc. 486 std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays; 487 std::unordered_map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers; 488 489 int mDisplayWidth; 490 int mDisplayHeight; 491 int mDisplayDpiX; 492 int mDisplayDpiY; 493 }; 494 495 } 496 #endif 497