Home | History | Annotate | Download | only in legacy
      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 <cutils/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 "common/vsoc/lib/screen_region_view.h"
     57 #include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
     58 #include <sync/sync.h>
     59 
     60 #include "base_composer.h"
     61 #include "geometry_utils.h"
     62 #include "hwcomposer_common.h"
     63 #include "stats_keeper.h"
     64 #include "vsoc_composer.h"
     65 
     66 using vsoc::screen::ScreenRegionView;
     67 
     68 #ifdef USE_OLD_HWCOMPOSER
     69 typedef cvd::BaseComposer InnerComposerType;
     70 #else
     71 typedef cvd::VSoCComposer InnerComposerType;
     72 #endif
     73 
     74 #ifdef GATHER_STATS
     75 typedef cvd::StatsKeepingComposer<InnerComposerType> ComposerType;
     76 #else
     77 typedef InnerComposerType ComposerType;
     78 #endif
     79 
     80 struct vsoc_hwc_composer_device_1_t {
     81   vsoc_hwc_device base;
     82   const hwc_procs_t* procs;
     83   pthread_t vsync_thread;
     84   int64_t vsync_base_timestamp;
     85   int32_t vsync_period_ns;
     86   ComposerType* composer;
     87 };
     88 
     89 namespace {
     90 
     91 std::string CompositionString(int type) {
     92   switch (type) {
     93     case HWC_FRAMEBUFFER:
     94       return "Framebuffer";
     95     case HWC_OVERLAY:
     96       return "Overlay";
     97     case HWC_BACKGROUND:
     98       return "Background";
     99     case HWC_FRAMEBUFFER_TARGET:
    100       return "FramebufferTarget";
    101 #if VSOC_PLATFORM_SDK_AFTER(K)
    102     case HWC_SIDEBAND:
    103       return "Sideband";
    104     case HWC_CURSOR_OVERLAY:
    105       return "CursorOverlay";
    106 #endif
    107     default:
    108       return std::string("Unknown (") + std::to_string(type) + ")";
    109   }
    110 }
    111 
    112 void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) {
    113   ALOGE("Layers:");
    114   for (int idx = 0; idx < num_layers; ++idx) {
    115     std::string log_line;
    116     if (idx == invalid) {
    117       log_line = "Invalid layer: ";
    118     }
    119     log_line +=
    120         "Composition Type: " + CompositionString(layers[idx].compositionType);
    121     ALOGE("%s", log_line.c_str());
    122   }
    123 }
    124 
    125 // Ensures that the layer does not include any inconsistencies
    126 bool IsValidLayer(const vsoc_hwc_layer& layer) {
    127   if (layer.flags & HWC_SKIP_LAYER) {
    128     // A layer we are asked to skip validate should not be marked as skip
    129     ALOGE("%s: Layer is marked as skip", __FUNCTION__);
    130     return false;
    131   }
    132   // Check displayFrame
    133   if (layer.displayFrame.left > layer.displayFrame.right ||
    134       layer.displayFrame.top > layer.displayFrame.bottom) {
    135     ALOGE(
    136         "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = "
    137         "%d, bottom = %d]",
    138         __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right,
    139         layer.displayFrame.top, layer.displayFrame.bottom);
    140     return false;
    141   }
    142   // Validate the handle
    143   if (private_handle_t::validate(layer.handle) != 0) {
    144     ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__);
    145     return false;
    146   }
    147   const private_handle_t* p_handle =
    148       reinterpret_cast<const private_handle_t*>(layer.handle);
    149   // Check sourceCrop
    150   if (layer.sourceCrop.left > layer.sourceCrop.right ||
    151       layer.sourceCrop.top > layer.sourceCrop.bottom) {
    152     ALOGE(
    153         "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = "
    154         "%d, bottom = %d]",
    155         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
    156         layer.sourceCrop.top, layer.sourceCrop.bottom);
    157     return false;
    158   }
    159   if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 ||
    160       layer.sourceCrop.right > p_handle->x_res ||
    161       layer.sourceCrop.bottom > p_handle->y_res) {
    162     ALOGE(
    163         "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, "
    164         "right = %d, top = %d, bottom = %d], handle = [width = %d, height = "
    165         "%d]",
    166         __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
    167         layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res,
    168         p_handle->y_res);
    169     return false;
    170   }
    171   return true;
    172 }
    173 
    174 bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) {
    175   if (num_layers == 0) {
    176     ALOGE("Composition requested with 0 layers");
    177     return false;
    178   }
    179   // Sometimes the hwcomposer receives a prepare and set calls with no other
    180   // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case
    181   // independently as a valid composition, but issue a warning about it.
    182   if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET &&
    183       layers[0].handle == NULL) {
    184     ALOGW("Received request for empty composition, treating as valid noop");
    185     return true;
    186   }
    187   // The FRAMEBUFFER_TARGET layer needs to be sane only if
    188   // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer
    189   // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer
    190   // marked overlay or framebuffer means that surfaceflinger decided to go for
    191   // OpenGL without asking the hwcomposer first)
    192   bool check_fb_target = true;
    193   for (int idx = 0; idx < num_layers; ++idx) {
    194     if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
    195       // There is at least one, so it needs to be checked.
    196       // It may have been set to false before, so ensure it's set to true.
    197       check_fb_target = true;
    198       break;
    199     }
    200     if (layers[idx].compositionType == HWC_OVERLAY) {
    201       // At least one overlay, we may not need to.
    202       check_fb_target = false;
    203     }
    204   }
    205 
    206   for (int idx = 0; idx < num_layers; ++idx) {
    207     switch (layers[idx].compositionType) {
    208     case HWC_FRAMEBUFFER_TARGET:
    209       // In the call to prepare() the framebuffer target does not have a valid
    210       // buffer_handle, so we don't validate it yet.
    211       if (on_set && check_fb_target && !IsValidLayer(layers[idx])) {
    212         ALOGE("%s: Invalid layer found", __FUNCTION__);
    213         LogLayers(num_layers, layers, idx);
    214         return false;
    215       }
    216       break;
    217     case HWC_OVERLAY:
    218       if (!(layers[idx].flags & HWC_SKIP_LAYER) &&
    219           !IsValidLayer(layers[idx])) {
    220         ALOGE("%s: Invalid layer found", __FUNCTION__);
    221         LogLayers(num_layers, layers, idx);
    222         return false;
    223       }
    224       break;
    225     }
    226   }
    227   return true;
    228 }
    229 
    230 }
    231 
    232 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    233 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) {
    234 #else
    235 static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays,
    236                             hwc_display_contents_1_t** displays) {
    237   if (!numDisplays || !displays) return 0;
    238 
    239   hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
    240 
    241   if (!list) return 0;
    242 #endif
    243   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
    244     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    245     return -1;
    246   }
    247   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
    248       list->numHwLayers, &list->hwLayers[0]);
    249   return 0;
    250 }
    251 
    252 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    253 int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy,
    254                  hwc_surface_t sur, hwc_layer_list_t* list) {
    255   if (list->numHwLayers == 1 &&
    256       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
    257     ALOGW("Received request for empty composition, treating as valid noop");
    258     return 0;
    259   }
    260   if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) {
    261     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    262     return -1;
    263   }
    264   return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)
    265       ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]);
    266 }
    267 #else
    268 static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays,
    269                         hwc_display_contents_1_t** displays) {
    270   if (!numDisplays || !displays) return 0;
    271 
    272   hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];
    273   if (!contents) return 0;
    274 
    275   vsoc_hwc_layer* layers = &contents->hwLayers[0];
    276   if (contents->numHwLayers == 1 &&
    277       layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
    278     ALOGW("Received request for empty composition, treating as valid noop");
    279     return 0;
    280   }
    281   if (!IsValidComposition(contents->numHwLayers, layers, true)) {
    282     LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
    283     return -1;
    284   }
    285   int retval =
    286       reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
    287           contents->numHwLayers, layers);
    288 
    289   int closedFds = 0;
    290   for (size_t index = 0; index < contents->numHwLayers; ++index) {
    291     if (layers[index].acquireFenceFd != -1) {
    292       close(layers[index].acquireFenceFd);
    293       layers[index].acquireFenceFd = -1;
    294       ++closedFds;
    295     }
    296   }
    297   if (closedFds) {
    298     ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
    299   }
    300 
    301   // TODO(ghartman): This should be set before returning. On the next set it
    302   // should be signalled when we load the new frame.
    303   contents->retireFenceFd = -1;
    304   return retval;
    305 }
    306 #endif
    307 
    308 static void vsoc_hwc_register_procs(vsoc_hwc_device* dev,
    309                                     const hwc_procs_t* procs) {
    310   struct vsoc_hwc_composer_device_1_t* pdev =
    311       (struct vsoc_hwc_composer_device_1_t*)dev;
    312   pdev->procs = procs;
    313 }
    314 
    315 static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) {
    316   struct vsoc_hwc_composer_device_1_t* pdev =
    317       (struct vsoc_hwc_composer_device_1_t*)dev;
    318 
    319   switch (what) {
    320     case HWC_BACKGROUND_LAYER_SUPPORTED:
    321       // we support the background layer
    322       value[0] = 0;
    323       break;
    324     case HWC_VSYNC_PERIOD:
    325       value[0] = pdev->vsync_period_ns;
    326       break;
    327     default:
    328       // unsupported query
    329       ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what);
    330       return -EINVAL;
    331   }
    332   return 0;
    333 }
    334 
    335 static int vsoc_hwc_event_control(
    336 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    337     vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) {
    338 #else
    339     vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) {
    340 #endif
    341 
    342   if (event == HWC_EVENT_VSYNC) {
    343     return 0;
    344   }
    345   return -EINVAL;
    346 }
    347 
    348 static void* hwc_vsync_thread(void* data) {
    349   struct vsoc_hwc_composer_device_1_t* pdev =
    350       (struct vsoc_hwc_composer_device_1_t*)data;
    351   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
    352 
    353   int64_t base_timestamp = pdev->vsync_base_timestamp;
    354   int64_t last_logged = base_timestamp / 1e9;
    355   int sent = 0;
    356   int last_sent = 0;
    357   static const int log_interval = 60;
    358   void (*vsync_proc)(const struct hwc_procs*, int, int64_t) = nullptr;
    359   bool log_no_procs = true, log_no_vsync = true;
    360   while (true) {
    361     struct timespec rt;
    362     if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
    363       ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
    364             strerror(errno));
    365     }
    366     int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
    367     // Given now's timestamp calculate the time of the next timestamp.
    368     timestamp += pdev->vsync_period_ns -
    369                  (timestamp - base_timestamp) % pdev->vsync_period_ns;
    370 
    371     rt.tv_sec = timestamp / 1e9;
    372     rt.tv_nsec = timestamp % static_cast<int32_t>(1e9);
    373     int err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rt, NULL);
    374     if (err == -1) {
    375       ALOGE("error in vsync thread: %s", strerror(errno));
    376       if (errno == EINTR) {
    377         continue;
    378       }
    379     }
    380 
    381     // The vsync thread is started on device open, it may run before the
    382     // registerProcs callback has a chance to be called, so we need to make sure
    383     // procs is not NULL before dereferencing it.
    384     if (pdev && pdev->procs) {
    385       vsync_proc = pdev->procs->vsync;
    386     } else if (log_no_procs) {
    387       log_no_procs = false;
    388       ALOGI("procs is not set yet, unable to deliver vsync event");
    389     }
    390     if (vsync_proc) {
    391       vsync_proc(const_cast<hwc_procs_t*>(pdev->procs), 0, timestamp);
    392       ++sent;
    393     } else if (log_no_vsync) {
    394       log_no_vsync = false;
    395       ALOGE("vsync callback is null (but procs was already set)");
    396     }
    397     if (rt.tv_sec - last_logged > log_interval) {
    398       ALOGI("Sent %d syncs in %ds", sent - last_sent, log_interval);
    399       last_logged = rt.tv_sec;
    400       last_sent = sent;
    401     }
    402   }
    403 
    404   return NULL;
    405 }
    406 
    407 static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) {
    408   if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL;
    409   return 0;
    410 }
    411 
    412 static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) {
    413   reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump(
    414       buff, buff_len);
    415 }
    416 
    417 static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp,
    418                                         uint32_t* configs, size_t* numConfigs) {
    419   if (*numConfigs == 0) return 0;
    420 
    421   if (IS_PRIMARY_DISPLAY(disp)) {
    422     configs[0] = 0;
    423     *numConfigs = 1;
    424     return 0;
    425   }
    426 
    427   return -EINVAL;
    428 }
    429 
    430 #if VSOC_PLATFORM_SDK_AFTER(J)
    431 static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev,
    432                                   const uint32_t attribute) {
    433   auto screen_view = ScreenRegionView::GetInstance();
    434   switch (attribute) {
    435     case HWC_DISPLAY_VSYNC_PERIOD:
    436       return pdev->vsync_period_ns;
    437     case HWC_DISPLAY_WIDTH:
    438       return screen_view->x_res();
    439     case HWC_DISPLAY_HEIGHT:
    440       return screen_view->y_res();
    441     case HWC_DISPLAY_DPI_X:
    442       ALOGI("Reporting DPI_X of %d", screen_view->dpi());
    443       // The number of pixels per thousand inches
    444       return screen_view->dpi() * 1000;
    445     case HWC_DISPLAY_DPI_Y:
    446       ALOGI("Reporting DPI_Y of %d", screen_view->dpi());
    447       // The number of pixels per thousand inches
    448       return screen_view->dpi() * 1000;
    449     default:
    450       ALOGE("unknown display attribute %u", attribute);
    451       return -EINVAL;
    452   }
    453 }
    454 
    455 static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp,
    456                                            uint32_t config __unused,
    457                                            const uint32_t* attributes,
    458                                            int32_t* values) {
    459   struct vsoc_hwc_composer_device_1_t* pdev =
    460       (struct vsoc_hwc_composer_device_1_t*)dev;
    461 
    462   if (!IS_PRIMARY_DISPLAY(disp)) {
    463     ALOGE("unknown display type %u", disp);
    464     return -EINVAL;
    465   }
    466 
    467   for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
    468     values[i] = vsoc_hwc_attribute(pdev, attributes[i]);
    469   }
    470 
    471   return 0;
    472 }
    473 #endif
    474 
    475 static int vsoc_hwc_close(hw_device_t* device) {
    476   struct vsoc_hwc_composer_device_1_t* dev =
    477       (struct vsoc_hwc_composer_device_1_t*)device;
    478   ALOGE("vsoc_hwc_close");
    479   pthread_kill(dev->vsync_thread, SIGTERM);
    480   pthread_join(dev->vsync_thread, NULL);
    481   delete dev->composer;
    482   delete dev;
    483   return 0;
    484 }
    485 
    486 static int vsoc_hwc_open(const struct hw_module_t* module, const char* name,
    487                          struct hw_device_t** device) {
    488   ALOGI("%s", __FUNCTION__);
    489   if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
    490     ALOGE("%s called with bad name %s", __FUNCTION__, name);
    491     return -EINVAL;
    492   }
    493 
    494   vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t();
    495   if (!dev) {
    496     ALOGE("%s failed to allocate dev", __FUNCTION__);
    497     return -ENOMEM;
    498   }
    499 
    500   int refreshRate = ScreenRegionView::GetInstance()->refresh_rate_hz();
    501   dev->vsync_period_ns = 1000000000 / refreshRate;
    502   struct timespec rt;
    503   if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
    504     ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
    505           strerror(errno));
    506   }
    507   dev->vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
    508 
    509   dev->base.common.tag = HARDWARE_DEVICE_TAG;
    510   dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION;
    511   dev->base.common.module = const_cast<hw_module_t*>(module);
    512   dev->base.common.close = vsoc_hwc_close;
    513 
    514   dev->base.prepare = vsoc_hwc_prepare;
    515   dev->base.set = vsoc_hwc_set;
    516   dev->base.query = vsoc_hwc_query;
    517   dev->base.registerProcs = vsoc_hwc_register_procs;
    518   dev->base.dump = vsoc_hwc_dump;
    519 #if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
    520   static hwc_methods_t hwc_methods = {vsoc_hwc_event_control};
    521   dev->base.methods = &hwc_methods;
    522 #else
    523   dev->base.blank = vsoc_hwc_blank;
    524   dev->base.eventControl = vsoc_hwc_event_control;
    525   dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs;
    526   dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes;
    527 #endif
    528   dev->composer =
    529       new ComposerType(dev->vsync_base_timestamp, dev->vsync_period_ns);
    530 
    531   int ret = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
    532   if (ret) {
    533     ALOGE("failed to start vsync thread: %s", strerror(ret));
    534     ret = -ret;
    535     delete dev;
    536   } else {
    537     *device = &dev->base.common;
    538   }
    539 
    540   return ret;
    541 }
    542 
    543 static struct hw_module_methods_t vsoc_hwc_module_methods = {
    544     vsoc_hwc_open,
    545 };
    546 
    547 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG,
    548                                      HWC_MODULE_API_VERSION_0_1,
    549                                      HARDWARE_HAL_API_VERSION,
    550                                      HWC_HARDWARE_MODULE_ID,
    551                                      "VSOC hwcomposer module",
    552                                      "Google",
    553                                      &vsoc_hwc_module_methods,
    554                                      NULL,
    555                                      {0}}};
    556