Home | History | Annotate | Download | only in drm_hwcomposer
      1 /*
      2  * Copyright (C) 2016 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 #include "drmdisplaycompositor.h"
     18 #include "drmhwcomposer.h"
     19 #include "drmresources.h"
     20 #include "platform.h"
     21 #include "vsyncworker.h"
     22 
     23 #include <hardware/hwcomposer2.h>
     24 
     25 #include <map>
     26 
     27 namespace android {
     28 
     29 class DrmHwcTwo : public hwc2_device_t {
     30  public:
     31   static int HookDevOpen(const struct hw_module_t *module, const char *name,
     32                          struct hw_device_t **dev);
     33 
     34   DrmHwcTwo();
     35 
     36   HWC2::Error Init();
     37 
     38  private:
     39   class HwcLayer {
     40    public:
     41     HWC2::Composition sf_type() const {
     42       return sf_type_;
     43     }
     44     HWC2::Composition validated_type() const {
     45       return validated_type_;
     46     }
     47     void accept_type_change() {
     48       sf_type_ = validated_type_;
     49     }
     50     void set_validated_type(HWC2::Composition type) {
     51       validated_type_ = type;
     52     }
     53     bool type_changed() const {
     54       return sf_type_ != validated_type_;
     55     }
     56 
     57     uint32_t z_order() const {
     58       return z_order_;
     59     }
     60 
     61     buffer_handle_t buffer() {
     62       return buffer_;
     63     }
     64     void set_buffer(buffer_handle_t buffer) {
     65       buffer_ = buffer;
     66     }
     67 
     68     int take_acquire_fence() {
     69       return acquire_fence_.Release();
     70     }
     71     void set_acquire_fence(int acquire_fence) {
     72       acquire_fence_.Set(dup(acquire_fence));
     73     }
     74 
     75     int release_fence() {
     76       return release_fence_.get();
     77     }
     78     int take_release_fence() {
     79       return release_fence_.Release();
     80     }
     81     void manage_release_fence() {
     82       release_fence_.Set(release_fence_raw_);
     83       release_fence_raw_ = -1;
     84     }
     85     OutputFd release_fence_output() {
     86       return OutputFd(&release_fence_raw_);
     87     }
     88 
     89     void PopulateDrmLayer(DrmHwcLayer *layer);
     90 
     91     // Layer hooks
     92     HWC2::Error SetCursorPosition(int32_t x, int32_t y);
     93     HWC2::Error SetLayerBlendMode(int32_t mode);
     94     HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence);
     95     HWC2::Error SetLayerColor(hwc_color_t color);
     96     HWC2::Error SetLayerCompositionType(int32_t type);
     97     HWC2::Error SetLayerDataspace(int32_t dataspace);
     98     HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame);
     99     HWC2::Error SetLayerPlaneAlpha(float alpha);
    100     HWC2::Error SetLayerSidebandStream(const native_handle_t *stream);
    101     HWC2::Error SetLayerSourceCrop(hwc_frect_t crop);
    102     HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
    103     HWC2::Error SetLayerTransform(int32_t transform);
    104     HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
    105     HWC2::Error SetLayerZOrder(uint32_t z);
    106 
    107    private:
    108     // sf_type_ stores the initial type given to us by surfaceflinger,
    109     // validated_type_ stores the type after running ValidateDisplay
    110     HWC2::Composition sf_type_ = HWC2::Composition::Invalid;
    111     HWC2::Composition validated_type_ = HWC2::Composition::Invalid;
    112 
    113     HWC2::BlendMode blending_ = HWC2::BlendMode::None;
    114     buffer_handle_t buffer_;
    115     UniqueFd acquire_fence_;
    116     int release_fence_raw_ = -1;
    117     UniqueFd release_fence_;
    118     hwc_rect_t display_frame_;
    119     float alpha_ = 1.0f;
    120     hwc_frect_t source_crop_;
    121     int32_t cursor_x_;
    122     int32_t cursor_y_;
    123     HWC2::Transform transform_ = HWC2::Transform::None;
    124     uint32_t z_order_ = 0;
    125     android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN;
    126   };
    127 
    128   struct HwcCallback {
    129     HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f)
    130         : data(d), func(f) {
    131     }
    132     hwc2_callback_data_t data;
    133     hwc2_function_pointer_t func;
    134   };
    135 
    136   class HwcDisplay {
    137    public:
    138     HwcDisplay(DrmResources *drm, std::shared_ptr<Importer> importer,
    139                const gralloc_module_t *gralloc, hwc2_display_t handle,
    140                HWC2::DisplayType type);
    141     HwcDisplay(const HwcDisplay &) = delete;
    142     HWC2::Error Init(std::vector<DrmPlane *> *planes);
    143 
    144     HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data,
    145                                       hwc2_function_pointer_t func);
    146 
    147     // HWC Hooks
    148     HWC2::Error AcceptDisplayChanges();
    149     HWC2::Error CreateLayer(hwc2_layer_t *layer);
    150     HWC2::Error DestroyLayer(hwc2_layer_t layer);
    151     HWC2::Error GetActiveConfig(hwc2_config_t *config);
    152     HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements,
    153                                            hwc2_layer_t *layers,
    154                                            int32_t *types);
    155     HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height,
    156                                        int32_t format, int32_t dataspace);
    157     HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
    158     HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
    159                                     int32_t *value);
    160     HWC2::Error GetDisplayConfigs(uint32_t *num_configs,
    161                                   hwc2_config_t *configs);
    162     HWC2::Error GetDisplayName(uint32_t *size, char *name);
    163     HWC2::Error GetDisplayRequests(int32_t *display_requests,
    164                                    uint32_t *num_elements, hwc2_layer_t *layers,
    165                                    int32_t *layer_requests);
    166     HWC2::Error GetDisplayType(int32_t *type);
    167     HWC2::Error GetDozeSupport(int32_t *support);
    168     HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
    169                                    float *max_luminance,
    170                                    float *max_average_luminance,
    171                                    float *min_luminance);
    172     HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers,
    173                                  int32_t *fences);
    174     HWC2::Error PresentDisplay(int32_t *retire_fence);
    175     HWC2::Error SetActiveConfig(hwc2_config_t config);
    176     HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
    177                                 int32_t dataspace, hwc_region_t damage);
    178     HWC2::Error SetColorMode(int32_t mode);
    179     HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
    180     HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence);
    181     HWC2::Error SetPowerMode(int32_t mode);
    182     HWC2::Error SetVsyncEnabled(int32_t enabled);
    183     HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
    184     HwcLayer &get_layer(hwc2_layer_t layer) {
    185       return layers_.at(layer);
    186     }
    187 
    188    private:
    189     void AddFenceToRetireFence(int fd);
    190 
    191     DrmResources *drm_;
    192     DrmDisplayCompositor compositor_;
    193     std::shared_ptr<Importer> importer_;
    194     std::unique_ptr<Planner> planner_;
    195     const gralloc_module_t *gralloc_;
    196 
    197     std::vector<DrmPlane *> primary_planes_;
    198     std::vector<DrmPlane *> overlay_planes_;
    199 
    200     VSyncWorker vsync_worker_;
    201     DrmConnector *connector_ = NULL;
    202     DrmCrtc *crtc_ = NULL;
    203     hwc2_display_t handle_;
    204     HWC2::DisplayType type_;
    205     uint32_t layer_idx_ = 0;
    206     std::map<hwc2_layer_t, HwcLayer> layers_;
    207     HwcLayer client_layer_;
    208     UniqueFd retire_fence_;
    209     UniqueFd next_retire_fence_;
    210     int32_t color_mode_;
    211 
    212     uint32_t frame_no_ = 0;
    213   };
    214 
    215   static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) {
    216     return static_cast<DrmHwcTwo *>(dev);
    217   }
    218 
    219   template <typename PFN, typename T>
    220   static hwc2_function_pointer_t ToHook(T function) {
    221     static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer");
    222     return reinterpret_cast<hwc2_function_pointer_t>(function);
    223   }
    224 
    225   template <typename T, typename HookType, HookType func, typename... Args>
    226   static T DeviceHook(hwc2_device_t *dev, Args... args) {
    227     DrmHwcTwo *hwc = toDrmHwcTwo(dev);
    228     return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...));
    229   }
    230 
    231   template <typename HookType, HookType func, typename... Args>
    232   static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle,
    233                              Args... args) {
    234     DrmHwcTwo *hwc = toDrmHwcTwo(dev);
    235     HwcDisplay &display = hwc->displays_.at(display_handle);
    236     return static_cast<int32_t>((display.*func)(std::forward<Args>(args)...));
    237   }
    238 
    239   template <typename HookType, HookType func, typename... Args>
    240   static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle,
    241                            hwc2_layer_t layer_handle, Args... args) {
    242     DrmHwcTwo *hwc = toDrmHwcTwo(dev);
    243     HwcDisplay &display = hwc->displays_.at(display_handle);
    244     HwcLayer &layer = display.get_layer(layer_handle);
    245     return static_cast<int32_t>((layer.*func)(std::forward<Args>(args)...));
    246   }
    247 
    248   // hwc2_device_t hooks
    249   static int HookDevClose(hw_device_t *dev);
    250   static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count,
    251                                      int32_t *out_capabilities);
    252   static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device,
    253                                                     int32_t descriptor);
    254 
    255   // Device functions
    256   HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height,
    257                                    int32_t *format,
    258                                    hwc2_display_t *display);
    259   HWC2::Error DestroyVirtualDisplay(hwc2_display_t display);
    260   void Dump(uint32_t *size, char *buffer);
    261   uint32_t GetMaxVirtualDisplayCount();
    262   HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data,
    263                                hwc2_function_pointer_t function);
    264 
    265   DrmResources drm_;
    266   std::shared_ptr<Importer> importer_;  // Shared with HwcDisplay
    267   const gralloc_module_t *gralloc_;
    268   std::map<hwc2_display_t, HwcDisplay> displays_;
    269   std::map<HWC2::Callback, HwcCallback> callbacks_;
    270 };
    271 }
    272