Home | History | Annotate | Download | only in cutf_cvm
      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 // Versions of hwcomposer we implement:
     18 // JB: 0.3
     19 // JB-MR1 to N : 1.1
     20 // N-MR1 to ... : We report 1.1 but SurfaceFlinger has the option to use an
     21 // adapter to treat our 1.1 hwcomposer as a 2.0. If SF stops using that adapter
     22 // to support 1.1 implementations it can be copied into cuttlefish from
     23 // frameworks/native/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.*
     24 
     25 #define LOG_TAG "hwc.cf_x86"
     26 
     27 #include <guest/libs/platform_support/api_level_fixes.h>
     28 
     29 #include <errno.h>
     30 #include <fcntl.h>
     31 #include <math.h>
     32 #include <poll.h>
     33 #include <pthread.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 
     37 #include <sys/ioctl.h>
     38 #include <sys/mman.h>
     39 #include <sys/resource.h>
     40 #include <sys/time.h>
     41 
     42 #include <string>
     43 
     44 #define HWC_REMOVE_DEPRECATED_VERSIONS 1
     45 
     46 #include <cutils/compiler.h>
     47 #include <log/log.h>
     48 #include <cutils/properties.h>
     49 #include <hardware/gralloc.h>
     50 #include <hardware/hardware.h>
     51 #include <hardware/hwcomposer.h>
     52 #include <hardware/hwcomposer_defs.h>
     53 #include <utils/String8.h>
     54 #include <utils/Vector.h>
     55 
     56 #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
     57 #include "guest/hals/hwcomposer/common/hwcomposer.h"
     58 #include <sync/sync.h>
     59 
     60 #include "base_composer.h"
     61 #include "geometry_utils.h"
     62 #include "hwcomposer.h"
     63 #include "vsoc_composer.h"
     64 
     65 #ifdef USE_OLD_HWCOMPOSER
     66 typedef cvd::BaseComposer InnerComposerType;
     67 #else
     68 typedef cvd::VSoCComposer InnerComposerType;
     69 #endif
     70 
     71 typedef InnerComposerType ComposerType;
     72 
     73 struct vsoc_hwc_composer_device_1_t {
     74   vsoc_hwc_device base;
     75   cvd::hwc_composer_device_data_t vsync_data;
     76   ComposerType* composer;
     77 };
     78 
     79 namespace {
     80 
     81 std::string CompositionString(int type) {
     82   switch (type) {
     83     case HWC_FRAMEBUFFER:
     84       return "Framebuffer";
     85     case HWC_OVERLAY:
     86       return "Overlay";
     87     case HWC_BACKGROUND:
     88       return "Background";
     89     case HWC_FRAMEBUFFER_TARGET:
     90       return "FramebufferTarget";
     91 #if VSOC_PLATFORM_SDK_AFTER(K)
     92     case HWC_SIDEBAND:
     93       return "Sideband";
     94     case HWC_CURSOR_OVERLAY:
     95       return "CursorOverlay";
     96 #endif
     97     default:
     98       return std::string("Unknown (") + std::to_string(type) + ")";
     99   }
    100 }
    101 
    102 void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) {
    103   ALOGE("Layers:");
    104   for (int idx = 0; idx < num_layers; ++idx) {
    105     std::string log_line;
    106     if (idx == invalid) {
    107       log_line = "Invalid layer: ";
    108     }
    109     log_line +=
    110         "Composition Type: " + CompositionString(layers[idx].compositionType);
    111     ALOGE("%s", log_line.c_str());
    112   }
    113 }
    114 
    115 // Ensures that the layer does not include any inconsistencies
    116 bool IsValidLayer(const vsoc_hwc_layer& layer) {
    117   if (layer.flags & HWC_SKIP_LAYER) {
    118     // A layer we are asked to skip validate should not be marked as skip
    119     ALOGE("%s: Layer is marked as skip", __FUNCTION__);
    120     return false;
    121   }
    122   // Check displayFrame
    123   if (layer.displayFrame.left > layer.displayFrame.right ||
    124       layer.displayFrame.top > layer.displayFrame.bottom) {
    125     ALOGE(
    126         "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = "
    127         "%d, bottom = %d]",
    128         __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right,
    129         layer.displayFrame.top, layer.displayFrame.bottom);
    130     return false;
    131   }
    132   // Validate the handle
    133   if (private_handle_t::validate(layer.handle) != 0) {
    134     ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__);
    135     return false;
    136   }
    137   const private_handle_t* p_handle =
    138       reinterpret_cast<const private_handle_t*>(layer.handle);
    139   // Check sourceCrop
    140   if (layer.sourceCrop.left > layer.sourceCrop.right ||
    141       layer.sourceCrop.top > layer.sourceCrop.bottom) {
    142     ALOGE(
    143         "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = "
    144         "%d, bottom = %d]",
    145         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
    146         layer.sourceCrop.top, layer.sourceCrop.bottom);
    147     return false;
    148   }
    149   if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 ||
    150       layer.sourceCrop.right > p_handle->x_res ||
    151       layer.sourceCrop.bottom > p_handle->y_res) {
    152     ALOGE(
    153         "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, "
    154         "right = %d, top = %d, bottom = %d], handle = [width = %d, height = "
    155         "%d]",
    156         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
    157         layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res,
    158         p_handle->y_res);
    159     return false;
    160   }
    161   return true;
    162 }
    163 
    164 bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) {
    165   if (num_layers == 0) {
    166     ALOGE("Composition requested with 0 layers");
    167     return false;
    168   }
    169   // Sometimes the hwcomposer receives a prepare and set calls with no other
    170   // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case
    171   // independently as a valid composition, but issue a warning about it.
    172   if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET &&
    173       layers[0].handle == NULL) {
    174     ALOGW("Received request for empty composition, treating as valid noop");
    175     return true;
    176   }
    177   // The FRAMEBUFFER_TARGET layer needs to be sane only if
    178   // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer
    179   // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer
    180   // marked overlay or framebuffer means that surfaceflinger decided to go for
    181   // OpenGL without asking the hwcomposer first)
    182   bool check_fb_target = true;
    183   for (int idx = 0; idx < num_layers; ++idx) {
    184     if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
    185       // There is at least one, so it needs to be checked.
    186       // It may have been set to false before, so ensure it's set to true.
    187       check_fb_target = true;
    188       break;
    189     }
    190     if (layers[idx].compositionType == HWC_OVERLAY) {
    191       // At least one overlay, we may not need to.
    192       check_fb_target = false;
    193     }
    194   }
    195 
    196   for (int idx = 0; idx < num_layers; ++idx) {
    197     switch (layers[idx].compositionType) {
    198     case HWC_FRAMEBUFFER_TARGET:
    199       // In the call to prepare() the framebuffer target does not have a valid
    200       // buffer_handle, so we don't validate it yet.
    201       if (on_set && check_fb_target && !IsValidLayer(layers[idx])) {
    202         ALOGE("%s: Invalid layer found", __FUNCTION__);
    203         LogLayers(num_layers, layers, idx);
    204         return false;
    205       }
    206       break;
    207     case HWC_OVERLAY:
    208       if (!(layers[idx].flags & HWC_SKIP_LAYER) &&
    209           !IsValidLayer(layers[idx])) {
    210         ALOGE("%s: Invalid layer found", __FUNCTION__);
    211         LogLayers(num_layers, layers, idx);
    212         return false;
    213       }
    214       break;
    215     }
    216   }
    217   return true;
    218 }
    219 
    220 }
    221 
    222 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    223 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) {
    224 #else
    225 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays,
    226                             hwc_display_contents_1_t** displays) {
    227   if (!numDisplays || !displays) return 0;
    228 
    229   hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
    230 
    231   if (!list) return 0;
    232 #endif
    233   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
    234     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    235     return -1;
    236   }
    237   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
    238       list->numHwLayers, &list->hwLayers[0]);
    239   return 0;
    240 }
    241 
    242 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    243 int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy,
    244                  hwc_surface_t sur, hwc_layer_list_t* list) {
    245   if (list->numHwLayers == 1 &&
    246       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
    247     ALOGW("Received request for empty composition, treating as valid noop");
    248     return 0;
    249   }
    250   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) {
    251     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    252     return -1;
    253   }
    254   return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)
    255       ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]);
    256 }
    257 #else
    258 static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays,
    259                         hwc_display_contents_1_t** displays) {
    260   if (!numDisplays || !displays) return 0;
    261 
    262   hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];
    263   if (!contents) return 0;
    264 
    265   vsoc_hwc_layer* layers = &contents->hwLayers[0];
    266   if (contents->numHwLayers == 1 &&
    267       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
    268     ALOGW("Received request for empty composition, treating as valid noop");
    269     return 0;
    270   }
    271   if (!IsValidComposition(contents->numHwLayers, layers, true)) {
    272     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    273     return -1;
    274   }
    275   int retval =
    276       reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
    277           contents->numHwLayers, layers);
    278 
    279   int closedFds = 0;
    280   for (size_t index = 0; index < contents->numHwLayers; ++index) {
    281     if (layers[index].acquireFenceFd != -1) {
    282       close(layers[index].acquireFenceFd);
    283       layers[index].acquireFenceFd = -1;
    284       ++closedFds;
    285     }
    286   }
    287   if (closedFds) {
    288     ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
    289   }
    290 
    291   // TODO(ghartman): This should be set before returning. On the next set it
    292   // should be signalled when we load the new frame.
    293   contents->retireFenceFd = -1;
    294   return retval;
    295 }
    296 #endif
    297 
    298 static void vsoc_hwc_register_procs(vsoc_hwc_device* dev,
    299                                     const hwc_procs_t* procs) {
    300   struct vsoc_hwc_composer_device_1_t* pdev =
    301       (struct vsoc_hwc_composer_device_1_t*)dev;
    302   pdev->vsync_data.procs = procs;
    303 }
    304 
    305 static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) {
    306   struct vsoc_hwc_composer_device_1_t* pdev =
    307       (struct vsoc_hwc_composer_device_1_t*)dev;
    308 
    309   switch (what) {
    310     case HWC_BACKGROUND_LAYER_SUPPORTED:
    311       // we support the background layer
    312       value[0] = 0;
    313       break;
    314     case HWC_VSYNC_PERIOD:
    315       value[0] = pdev->vsync_data.vsync_period_ns;
    316       break;
    317     default:
    318       // unsupported query
    319       ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what);
    320       return -EINVAL;
    321   }
    322   return 0;
    323 }
    324 
    325 static int vsoc_hwc_event_control(
    326 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    327     vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) {
    328 #else
    329     vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) {
    330 #endif
    331 
    332   if (event == HWC_EVENT_VSYNC) {
    333     return 0;
    334   }
    335   return -EINVAL;
    336 }
    337 
    338 static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) {
    339   if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL;
    340   return 0;
    341 }
    342 
    343 static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) {
    344   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump(
    345       buff, buff_len);
    346 }
    347 
    348 static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp,
    349                                         uint32_t* configs, size_t* numConfigs) {
    350   if (*numConfigs == 0) return 0;
    351 
    352   if (IS_PRIMARY_DISPLAY(disp)) {
    353     configs[0] = 0;
    354     *numConfigs = 1;
    355     return 0;
    356   }
    357 
    358   return -EINVAL;
    359 }
    360 
    361 #if VSOC_PLATFORM_SDK_AFTER(J)
    362 static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev,
    363                                   const uint32_t attribute) {
    364   switch (attribute) {
    365     case HWC_DISPLAY_VSYNC_PERIOD:
    366       return pdev->vsync_data.vsync_period_ns;
    367     case HWC_DISPLAY_WIDTH:
    368       return pdev->composer->x_res();
    369     case HWC_DISPLAY_HEIGHT:
    370       return pdev->composer->y_res();
    371     case HWC_DISPLAY_DPI_X:
    372       ALOGI("Reporting DPI_X of %d", pdev->composer->dpi());
    373       // The number of pixels per thousand inches
    374       return pdev->composer->dpi() * 1000;
    375     case HWC_DISPLAY_DPI_Y:
    376       ALOGI("Reporting DPI_Y of %d", pdev->composer->dpi());
    377       // The number of pixels per thousand inches
    378       return pdev->composer->dpi() * 1000;
    379     default:
    380       ALOGE("unknown display attribute %u", attribute);
    381       return -EINVAL;
    382   }
    383 }
    384 
    385 static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp,
    386                                            uint32_t config __unused,
    387                                            const uint32_t* attributes,
    388                                            int32_t* values) {
    389   struct vsoc_hwc_composer_device_1_t* pdev =
    390       (struct vsoc_hwc_composer_device_1_t*)dev;
    391 
    392   if (!IS_PRIMARY_DISPLAY(disp)) {
    393     ALOGE("unknown display type %u", disp);
    394     return -EINVAL;
    395   }
    396 
    397   for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
    398     values[i] = vsoc_hwc_attribute(pdev, attributes[i]);
    399   }
    400 
    401   return 0;
    402 }
    403 #endif
    404 
    405 static int vsoc_hwc_close(hw_device_t* device) {
    406   struct vsoc_hwc_composer_device_1_t* dev =
    407       (struct vsoc_hwc_composer_device_1_t*)device;
    408   ALOGE("vsoc_hwc_close");
    409   pthread_kill(dev->vsync_data.vsync_thread, SIGTERM);
    410   pthread_join(dev->vsync_data.vsync_thread, NULL);
    411   delete dev->composer;
    412   delete dev;
    413   return 0;
    414 }
    415 
    416 static int vsoc_hwc_open(const struct hw_module_t* module, const char* name,
    417                          struct hw_device_t** device) {
    418   ALOGI("%s", __FUNCTION__);
    419   if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
    420     ALOGE("%s called with bad name %s", __FUNCTION__, name);
    421     return -EINVAL;
    422   }
    423 
    424   vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t();
    425   if (!dev) {
    426     ALOGE("%s failed to allocate dev", __FUNCTION__);
    427     return -ENOMEM;
    428   }
    429 
    430   struct timespec rt;
    431   if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
    432     ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
    433           strerror(errno));
    434   }
    435   dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
    436 
    437   dev->base.common.tag = HARDWARE_DEVICE_TAG;
    438   dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION;
    439   dev->base.common.module = const_cast<hw_module_t*>(module);
    440   dev->base.common.close = vsoc_hwc_close;
    441 
    442   dev->base.prepare = vsoc_hwc_prepare;
    443   dev->base.set = vsoc_hwc_set;
    444   dev->base.query = vsoc_hwc_query;
    445   dev->base.registerProcs = vsoc_hwc_register_procs;
    446   dev->base.dump = vsoc_hwc_dump;
    447 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    448   static hwc_methods_t hwc_methods = {vsoc_hwc_event_control};
    449   dev->base.methods = &hwc_methods;
    450 #else
    451   dev->base.blank = vsoc_hwc_blank;
    452   dev->base.eventControl = vsoc_hwc_event_control;
    453   dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs;
    454   dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes;
    455 #endif
    456   dev->composer = new ComposerType(dev->vsync_data.vsync_base_timestamp);
    457   dev->vsync_data.vsync_period_ns = 1000000000 / dev->composer->refresh_rate();
    458   int ret = pthread_create(&dev->vsync_data.vsync_thread,
    459                            NULL, cvd::hwc_vsync_thread, &dev->vsync_data);
    460   if (ret) {
    461     ALOGE("failed to start vsync thread: %s", strerror(ret));
    462     ret = -ret;
    463     delete dev;
    464   } else {
    465     *device = &dev->base.common;
    466   }
    467 
    468   return ret;
    469 }
    470 
    471 static struct hw_module_methods_t vsoc_hwc_module_methods = {
    472     vsoc_hwc_open,
    473 };
    474 
    475 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG,
    476                                      HWC_MODULE_API_VERSION_0_1,
    477                                      HARDWARE_HAL_API_VERSION,
    478                                      HWC_HARDWARE_MODULE_ID,
    479                                      "VSOC hwcomposer module",
    480                                      "Google",
    481                                      &vsoc_hwc_module_methods,
    482                                      NULL,
    483                                      {0}}};
    484