Home | History | Annotate | Download | only in hwc
      1 /*
      2 * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
      3 *
      4 * Redistribution and use in source and binary forms, with or without
      5 * modification, are permitted provided that the following conditions are
      6 * met:
      7 *     * Redistributions of source code must retain the above copyright
      8 *       notice, this list of conditions and the following disclaimer.
      9 *     * Redistributions in binary form must reproduce the above
     10 *       copyright notice, this list of conditions and the following
     11 *       disclaimer in the documentation and/or other materials provided
     12 *       with the distribution.
     13 *     * Neither the name of The Linux Foundation nor the names of its
     14 *       contributors may be used to endorse or promote products derived
     15 *       from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <utils/constants.h>
     31 #include <utils/debug.h>
     32 #include <sync/sync.h>
     33 #include <stdarg.h>
     34 #include <gr.h>
     35 
     36 #include "hwc_display_virtual.h"
     37 #include "hwc_debugger.h"
     38 
     39 #define __CLASS__ "HWCDisplayVirtual"
     40 
     41 namespace sdm {
     42 
     43 int HWCDisplayVirtual::Create(CoreInterface *core_intf, hwc_procs_t const **hwc_procs,
     44                               uint32_t primary_width, uint32_t primary_height,
     45                               hwc_display_contents_1_t *content_list,
     46                               HWCDisplay **hwc_display) {
     47   int status = 0;
     48   HWCDisplayVirtual *hwc_display_virtual = new HWCDisplayVirtual(core_intf, hwc_procs);
     49   uint32_t virtual_width = 0, virtual_height = 0;
     50 
     51   status = hwc_display_virtual->Init();
     52   if (status) {
     53     delete hwc_display_virtual;
     54     return status;
     55   }
     56 
     57   status = hwc_display_virtual->SetPowerMode(HWC_POWER_MODE_NORMAL);
     58   if (status) {
     59     Destroy(hwc_display_virtual);
     60     return status;
     61   }
     62 
     63   // TODO(user): Need to update resolution(and not aligned resolution) on writeback.
     64   status = hwc_display_virtual->SetOutputSliceFromMetadata(content_list);
     65   if (status) {
     66     Destroy(hwc_display_virtual);
     67     return status;
     68   }
     69 
     70   hwc_display_virtual->GetMixerResolution(&virtual_width, &virtual_height);
     71 
     72   if (content_list->numHwLayers < 1) {
     73     Destroy(hwc_display_virtual);
     74     return -1;
     75   }
     76 
     77   hwc_layer_1_t &fb_layer = content_list->hwLayers[content_list->numHwLayers-1];
     78   int fb_width = fb_layer.displayFrame.right - fb_layer.displayFrame.left;
     79   int fb_height = fb_layer.displayFrame.bottom - fb_layer.displayFrame.top;
     80 
     81   status = hwc_display_virtual->SetFrameBufferResolution(UINT32(fb_width), UINT32(fb_height));
     82 
     83   if (status) {
     84     Destroy(hwc_display_virtual);
     85     return status;
     86   }
     87 
     88   *hwc_display = static_cast<HWCDisplay *>(hwc_display_virtual);
     89 
     90   return 0;
     91 }
     92 
     93 void HWCDisplayVirtual::Destroy(HWCDisplay *hwc_display) {
     94   hwc_display->Deinit();
     95   delete hwc_display;
     96 }
     97 
     98 HWCDisplayVirtual::HWCDisplayVirtual(CoreInterface *core_intf, hwc_procs_t const **hwc_procs)
     99   : HWCDisplay(core_intf, hwc_procs, kVirtual, HWC_DISPLAY_VIRTUAL, false, NULL,
    100                DISPLAY_CLASS_VIRTUAL) {
    101 }
    102 
    103 int HWCDisplayVirtual::Init() {
    104   output_buffer_ = new LayerBuffer();
    105   if (!output_buffer_) {
    106     return -ENOMEM;
    107   }
    108 
    109   return HWCDisplay::Init();
    110 }
    111 
    112 int HWCDisplayVirtual::Deinit() {
    113   int status = 0;
    114 
    115   status = HWCDisplay::Deinit();
    116   if (status) {
    117     return status;
    118   }
    119 
    120   if (output_buffer_) {
    121     delete output_buffer_;
    122     output_buffer_ = NULL;
    123   }
    124 
    125   return status;
    126 }
    127 
    128 int HWCDisplayVirtual::Prepare(hwc_display_contents_1_t *content_list) {
    129   int status = 0;
    130 
    131   status = SetOutputSliceFromMetadata(content_list);
    132   if (status) {
    133     return status;
    134   }
    135 
    136   if (display_paused_) {
    137     MarkLayersForGPUBypass(content_list);
    138     return status;
    139   }
    140 
    141   status = AllocateLayerStack(content_list);
    142   if (status) {
    143     return status;
    144   }
    145 
    146   status = SetOutputBuffer(content_list);
    147   if (status) {
    148     return status;
    149   }
    150 
    151   status = PrePrepareLayerStack(content_list);
    152   if (status) {
    153     return status;
    154   }
    155 
    156   status = PrepareLayerStack(content_list);
    157   if (status) {
    158     return status;
    159   }
    160 
    161   return 0;
    162 }
    163 
    164 int HWCDisplayVirtual::Commit(hwc_display_contents_1_t *content_list) {
    165   int status = 0;
    166   if (display_paused_) {
    167     DisplayError error = display_intf_->Flush();
    168     if (error != kErrorNone) {
    169       DLOGE("Flush failed. Error = %d", error);
    170     }
    171     return status;
    172   }
    173 
    174   CommitOutputBufferParams(content_list);
    175 
    176   status = HWCDisplay::CommitLayerStack(content_list);
    177   if (status) {
    178     return status;
    179   }
    180 
    181   if (dump_frame_count_ && !flush_ && dump_output_layer_) {
    182     const private_handle_t *output_handle = (const private_handle_t *)(content_list->outbuf);
    183     if (output_handle && output_handle->base) {
    184       BufferInfo buffer_info;
    185       buffer_info.buffer_config.width = static_cast<uint32_t>(output_handle->width);
    186       buffer_info.buffer_config.height = static_cast<uint32_t>(output_handle->height);
    187       buffer_info.buffer_config.format = GetSDMFormat(output_handle->format, output_handle->flags);
    188       buffer_info.alloc_buffer_info.size = static_cast<uint32_t>(output_handle->size);
    189       DumpOutputBuffer(buffer_info, reinterpret_cast<void *>(output_handle->base),
    190                        layer_stack_.retire_fence_fd);
    191     }
    192   }
    193 
    194   status = HWCDisplay::PostCommitLayerStack(content_list);
    195   if (status) {
    196     return status;
    197   }
    198 
    199   return 0;
    200 }
    201 
    202 int HWCDisplayVirtual::SetOutputSliceFromMetadata(hwc_display_contents_1_t *content_list) {
    203   const private_handle_t *output_handle =
    204         static_cast<const private_handle_t *>(content_list->outbuf);
    205   DisplayError error = kErrorNone;
    206   int status = 0;
    207 
    208   if (output_handle) {
    209     int output_handle_format = output_handle->format;
    210     if (output_handle_format == HAL_PIXEL_FORMAT_RGBA_8888) {
    211       output_handle_format = HAL_PIXEL_FORMAT_RGBX_8888;
    212     }
    213 
    214     LayerBufferFormat format = GetSDMFormat(output_handle_format, output_handle->flags);
    215     if (format == kFormatInvalid) {
    216       return -EINVAL;
    217     }
    218 
    219     int active_width;
    220     int active_height;
    221 
    222     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, active_width,
    223                                                           active_height);
    224 
    225     if ((active_width != INT(output_buffer_->width)) ||
    226         (active_height!= INT(output_buffer_->height)) ||
    227         (format != output_buffer_->format)) {
    228       // Populate virtual display attributes based on displayFrame of FBT.
    229       // For DRC, use width and height populated in metadata (unaligned values)
    230       // for setting attributes of virtual display. This is needed because if
    231       // we use aligned width and height, scaling will be required for FBT layer.
    232       DisplayConfigVariableInfo variable_info;
    233       hwc_layer_1_t &fbt_layer = content_list->hwLayers[content_list->numHwLayers-1];
    234       hwc_rect_t &frame = fbt_layer.displayFrame;
    235       int fbt_width = frame.right - frame.left;
    236       int fbt_height = frame.bottom - frame.top;
    237       const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(output_handle->base_metadata);
    238       if (meta_data && meta_data->operation & UPDATE_BUFFER_GEOMETRY) {
    239         variable_info.x_pixels = UINT32(meta_data->bufferDim.sliceWidth);
    240         variable_info.y_pixels = UINT32(meta_data->bufferDim.sliceHeight);
    241       } else {
    242         variable_info.x_pixels = UINT32(fbt_width);
    243         variable_info.y_pixels = UINT32(fbt_height);
    244       }
    245       // TODO(user): Need to get the framerate of primary display and update it.
    246       variable_info.fps = 60;
    247 
    248       error = display_intf_->SetActiveConfig(&variable_info);
    249       if (error != kErrorNone) {
    250         return -EINVAL;
    251       }
    252 
    253       status = SetOutputBuffer(content_list);
    254       if (status) {
    255         return status;
    256       }
    257     }
    258   }
    259 
    260   return 0;
    261 }
    262 
    263 int HWCDisplayVirtual::SetOutputBuffer(hwc_display_contents_1_t *content_list) {
    264   const private_handle_t *output_handle =
    265         static_cast<const private_handle_t *>(content_list->outbuf);
    266 
    267   if (output_handle) {
    268     int output_handle_format = output_handle->format;
    269 
    270     if (output_handle_format == HAL_PIXEL_FORMAT_RGBA_8888) {
    271       output_handle_format = HAL_PIXEL_FORMAT_RGBX_8888;
    272     }
    273 
    274     output_buffer_->format = GetSDMFormat(output_handle_format, output_handle->flags);
    275 
    276     if (output_buffer_->format == kFormatInvalid) {
    277       return -EINVAL;
    278     }
    279 
    280     int aligned_width, aligned_height;
    281     int unaligned_width, unaligned_height;
    282 
    283     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(output_handle, aligned_width,
    284                                                           aligned_height);
    285     AdrenoMemInfo::getInstance().getUnalignedWidthAndHeight(output_handle, unaligned_width,
    286                                                             unaligned_height);
    287 
    288     output_buffer_->width = UINT32(aligned_width);
    289     output_buffer_->height = UINT32(aligned_height);
    290     output_buffer_->unaligned_width = UINT32(unaligned_width);
    291     output_buffer_->unaligned_height = UINT32(unaligned_height);
    292     output_buffer_->flags.secure = 0;
    293     output_buffer_->flags.video = 0;
    294 
    295     const MetaData_t *meta_data = reinterpret_cast<MetaData_t *>(output_handle->base_metadata);
    296     if (meta_data && SetCSC(meta_data, &output_buffer_->color_metadata) != kErrorNone) {
    297       return kErrorNotSupported;
    298     }
    299 
    300     // TZ Protected Buffer - L1
    301     if (output_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
    302       output_buffer_->flags.secure = 1;
    303     }
    304   }
    305 
    306   layer_stack_.output_buffer = output_buffer_;
    307 
    308   return 0;
    309 }
    310 
    311 void HWCDisplayVirtual::CommitOutputBufferParams(hwc_display_contents_1_t *content_list) {
    312   const private_handle_t *output_handle =
    313         static_cast<const private_handle_t *>(content_list->outbuf);
    314 
    315   // Fill output buffer parameters (width, height, format, plane information, fence)
    316   output_buffer_->acquire_fence_fd = content_list->outbufAcquireFenceFd;
    317 
    318   if (output_handle) {
    319     // ToDo: Need to extend for non-RGB formats
    320     output_buffer_->planes[0].fd = output_handle->fd;
    321     output_buffer_->planes[0].offset = output_handle->offset;
    322     output_buffer_->planes[0].stride = UINT32(output_handle->width);
    323   }
    324 }
    325 
    326 void HWCDisplayVirtual::SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type) {
    327   HWCDisplay::SetFrameDumpConfig(count, bit_mask_layer_type);
    328   dump_output_layer_ = ((bit_mask_layer_type & (1 << OUTPUT_LAYER_DUMP)) != 0);
    329 
    330   DLOGI("output_layer_dump_enable %d", dump_output_layer_);
    331 }
    332 
    333 }  // namespace sdm
    334 
    335