Home | History | Annotate | Download | only in hwc
      1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *  * Redistributions of source code must retain the above copyright
      7 *    notice, this list of conditions and the following disclaimer.
      8 *  * Redistributions in binary form must reproduce the above
      9 *    copyright notice, this list of conditions and the following
     10 *    disclaimer in the documentation and/or other materials provided
     11 *    with the distribution.
     12 *  * Neither the name of The Linux Foundation nor the names of its
     13 *    contributors may be used to endorse or promote products derived
     14 *    from this software without specific prior written permission.
     15 *
     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 * Portions formerly licensed under Apache License, Version 2.0, are re licensed
     30 * under section 4 of Apache License, Version 2.0.
     31 
     32 * Copyright (C) 2010 The Android Open Source Project
     33 
     34 * Not a Contribution.
     35 
     36 * Licensed under the Apache License, Version 2.0 (the "License");
     37 * you may not use this file except in compliance with the License.
     38 * You may obtain a copy of the License at
     39 
     40 * http://www.apache.org/licenses/LICENSE-2.0
     41 
     42 * Unless required by applicable law or agreed to in writing, software
     43 * distributed under the License is distributed on an "AS IS" BASIS,
     44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     45 * See the License for the specific language governing permissions and
     46 * limitations under the License.
     47 */
     48 
     49 #include <hardware/hardware.h>
     50 #include <sync/sync.h>
     51 #include <copybit.h>
     52 #include <memalloc.h>
     53 #include <alloc_controller.h>
     54 #include <gr.h>
     55 
     56 #include <utils/constants.h>
     57 #include <utils/rect.h>
     58 #include <utils/formats.h>
     59 #include <algorithm>
     60 
     61 #include "blit_engine_c2d.h"
     62 #include "hwc_debugger.h"
     63 
     64 #define __CLASS__ "BlitEngineC2D"
     65 
     66 // TODO(user): Remove pragma after fixing sign conversion errors
     67 #if defined(__clang__)
     68 #pragma clang diagnostic push
     69 #pragma clang diagnostic ignored "-Wsign-conversion"
     70 #endif
     71 
     72 namespace sdm {
     73 
     74 
     75 BlitEngineC2d::RegionIterator::RegionIterator(LayerRectArray rect) {
     76   rect_array = rect;
     77   r.end = INT(rect.count);
     78   r.current = 0;
     79   this->next = iterate;
     80 }
     81 
     82 int BlitEngineC2d::RegionIterator::iterate(copybit_region_t const *self, copybit_rect_t *rect) {
     83   if (!self || !rect) {
     84     DLOGE("iterate invalid parameters");
     85     return 0;
     86   }
     87 
     88   RegionIterator const *me = static_cast<RegionIterator const*>(self);
     89   if (me->r.current != me->r.end) {
     90     rect->l = INT(me->rect_array.rect[me->r.current].left);
     91     rect->t = INT(me->rect_array.rect[me->r.current].top);
     92     rect->r = INT(me->rect_array.rect[me->r.current].right);
     93     rect->b = INT(me->rect_array.rect[me->r.current].bottom);
     94     me->r.current++;
     95     return 1;
     96   }
     97   return 0;
     98 }
     99 
    100 BlitEngineC2d::BlitEngineC2d() {
    101   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
    102     blit_target_buffer_[i] = NULL;
    103     release_fence_fd_[i] = -1;
    104   }
    105 }
    106 
    107 BlitEngineC2d::~BlitEngineC2d() {
    108   if (blit_engine_c2d_) {
    109     copybit_close(blit_engine_c2d_);
    110     blit_engine_c2d_ = NULL;
    111   }
    112   FreeBlitTargetBuffers();
    113 }
    114 
    115 int BlitEngineC2d::Init() {
    116   hw_module_t const *module;
    117   if (hw_get_module("copybit", &module) == 0) {
    118     if (copybit_open(module, &blit_engine_c2d_) < 0) {
    119       DLOGI("CopyBitC2D Open failed.");
    120       return -1;
    121     }
    122     DLOGI("Opened Copybit Module");
    123   } else {
    124     DLOGI("Copybit HW Module not found");
    125     return -1;
    126   }
    127 
    128   return 0;
    129 }
    130 
    131 void BlitEngineC2d::DeInit() {
    132   FreeBlitTargetBuffers();
    133   if (blit_engine_c2d_) {
    134     copybit_close(blit_engine_c2d_);
    135     blit_engine_c2d_ = NULL;
    136   }
    137 }
    138 
    139 int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format,
    140                                              uint32_t usage) {
    141   int status = 0;
    142   if (width <= 0 || height <= 0) {
    143     return false;
    144   }
    145 
    146   if (blit_target_buffer_[0]) {
    147     // Free and reallocate the buffers if the w/h changes
    148     if (INT(width) != blit_target_buffer_[0]->width ||
    149         INT(height) != blit_target_buffer_[0]->height) {
    150       FreeBlitTargetBuffers();
    151     }
    152   }
    153 
    154   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
    155     if (blit_target_buffer_[i] == NULL) {
    156       status = alloc_buffer(&blit_target_buffer_[i], width, height, format, usage);
    157     }
    158     if (status < 0) {
    159       DLOGE("Allocation of Blit target Buffer failed");
    160       FreeBlitTargetBuffers();
    161       break;
    162     }
    163   }
    164 
    165   return status;
    166 }
    167 
    168 void BlitEngineC2d::FreeBlitTargetBuffers() {
    169   for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
    170     private_handle_t **target_buffer = &blit_target_buffer_[i];
    171     if (*target_buffer) {
    172       // Free the valid fence
    173       if (release_fence_fd_[i] >= 0) {
    174         close(release_fence_fd_[i]);
    175         release_fence_fd_[i] = -1;
    176       }
    177       free_buffer(*target_buffer);
    178       *target_buffer = NULL;
    179     }
    180   }
    181 }
    182 
    183 int BlitEngineC2d::ClearTargetBuffer(private_handle_t* hnd, const LayerRect& rect) {
    184   int status = 0;
    185   copybit_rect_t clear_rect = {INT(rect.left), INT(rect.top), INT(rect.right), INT(rect.bottom)};
    186 
    187   copybit_image_t buffer;
    188   buffer.w = ALIGN((hnd->width), 32);
    189   buffer.h = hnd->height;
    190   buffer.format = hnd->format;
    191   buffer.base = reinterpret_cast<void *>(hnd->base);
    192   buffer.handle = reinterpret_cast<native_handle_t *>(hnd);
    193   int dst_format_mode = COPYBIT_LINEAR;
    194   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    195     dst_format_mode = COPYBIT_UBWC_COMPRESSED;
    196   }
    197   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DST_FORMAT_MODE, dst_format_mode);
    198 
    199   status = blit_engine_c2d_->clear(blit_engine_c2d_, &buffer, &clear_rect);
    200   return status;
    201 }
    202 
    203 void BlitEngineC2d::PostCommit(LayerStack *layer_stack) {
    204   int fence_fd = -1;
    205   uint32_t count = 0;
    206   int fd = -1;
    207 
    208   for (uint32_t i = blit_target_start_index_-2; (i > 0) && (count < num_blit_target_); i--) {
    209     Layer *layer = layer_stack->layers.at(i);
    210     LayerBuffer &layer_buffer = layer->input_buffer;
    211     if (layer->composition == kCompositionBlit) {
    212       int index = blit_target_start_index_ + count;
    213       layer_buffer.release_fence_fd =
    214         layer_stack->layers.at(index)->input_buffer.release_fence_fd;
    215       fence_fd = layer_buffer.release_fence_fd;
    216       close(layer_buffer.acquire_fence_fd);
    217       layer_buffer.acquire_fence_fd = -1;
    218       layer_stack->layers.at(index)->input_buffer.release_fence_fd = -1;
    219       fd = layer_stack->layers.at(index)->input_buffer.acquire_fence_fd;
    220       layer_stack->layers.at(index)->input_buffer.acquire_fence_fd = -1;
    221       count++;
    222     }
    223   }
    224 
    225   if (fd >= 0) {
    226     // Close the C2D fence FD
    227     close(fd);
    228   }
    229   SetReleaseFence(fence_fd);
    230 }
    231 
    232 // Sync wait to close the previous fd
    233 void BlitEngineC2d::SetReleaseFence(int fd) {
    234   if (release_fence_fd_[current_blit_target_index_] >= 0) {
    235     int ret = -1;
    236     ret = sync_wait(release_fence_fd_[current_blit_target_index_], 1000);
    237     if (ret < 0) {
    238       DLOGE("sync_wait error! errno = %d, err str = %s", errno, strerror(errno));
    239     }
    240     close(release_fence_fd_[current_blit_target_index_]);
    241   }
    242   release_fence_fd_[current_blit_target_index_] = dup(fd);
    243 }
    244 
    245 bool BlitEngineC2d::BlitActive() {
    246   return blit_active_;
    247 }
    248 
    249 void BlitEngineC2d::SetFrameDumpConfig(uint32_t count) {
    250   dump_frame_count_ = count;
    251   dump_frame_index_ = 0;
    252 }
    253 
    254 int BlitEngineC2d::Prepare(LayerStack *layer_stack) {
    255   blit_target_start_index_ = 0;
    256 
    257   uint32_t layer_count = UINT32(layer_stack->layers.size());
    258   uint32_t gpu_target_index = layer_count - 1;  // default assumption
    259   uint32_t i = 0;
    260 
    261   for (; i < layer_count; i++) {
    262     Layer *layer = layer_stack->layers.at(i);
    263 
    264     // No 10 bit support for C2D
    265     if (Is10BitFormat(layer->input_buffer.format)) {
    266       return -1;
    267     }
    268 
    269     if (layer->composition == kCompositionGPUTarget) {
    270       // Need FBT size for allocating buffers
    271       gpu_target_index = i;
    272       break;
    273     }
    274   }
    275 
    276   if ((layer_count - 1) == gpu_target_index) {
    277     // No blit target layer
    278     return -1;
    279   }
    280 
    281   blit_target_start_index_ = ++i;
    282   num_blit_target_ = layer_count - blit_target_start_index_;
    283 
    284   LayerBuffer &layer_buffer = layer_stack->layers.at(gpu_target_index)->input_buffer;
    285   int fbwidth = INT(layer_buffer.unaligned_width);
    286   int fbheight = INT(layer_buffer.unaligned_height);
    287   if ((fbwidth < 0) || (fbheight < 0)) {
    288     return -1;
    289   }
    290 
    291   current_blit_target_index_ = (current_blit_target_index_ + 1) % kNumBlitTargetBuffers;
    292   int k = blit_target_start_index_;
    293 
    294   for (uint32_t j = 0; j < num_blit_target_; j++, k++) {
    295     Layer *layer = layer_stack->layers.at(k);
    296     LayerBuffer &layer_buffer = layer->input_buffer;
    297     int aligned_w = 0;
    298     int aligned_h = 0;
    299 
    300     // Set the buffer height and width
    301     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(fbwidth, fbheight/3,
    302                    INT(HAL_PIXEL_FORMAT_RGBA_8888), 0, aligned_w, aligned_h);
    303     layer_buffer.width = aligned_w;
    304     layer_buffer.height = aligned_h;
    305     layer_buffer.unaligned_width = fbwidth;
    306     layer_buffer.unaligned_height = fbheight/3;
    307 
    308     layer->plane_alpha = 0xFF;
    309     layer->blending = kBlendingOpaque;
    310     layer->composition = kCompositionBlitTarget;
    311     layer->frame_rate = layer_stack->layers.at(gpu_target_index)->frame_rate;
    312   }
    313 
    314   return 0;
    315 }
    316 
    317 int BlitEngineC2d::PreCommit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
    318   int status = 0;
    319   uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
    320   int target_width = 0;
    321   int target_height = 0;
    322   int target_aligned_width = 0;
    323   int target_aligned_height = 0;
    324   uint32_t processed_blit = 0;
    325   LayerRect dst_rects[kMaxBlitTargetLayers];
    326   bool blit_needed = false;
    327   uint32_t usage = 0;
    328 
    329   if (!num_app_layers) {
    330     return -1;
    331   }
    332 
    333   for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_); i--) {
    334     Layer *layer = layer_stack->layers.at(i);
    335     if (layer->composition != kCompositionBlit) {
    336       continue;
    337     }
    338     blit_needed = true;
    339     layer_stack->flags.attributes_changed = true;
    340 
    341     Layer *blit_layer = layer_stack->layers.at(blit_target_start_index_ + processed_blit);
    342     LayerRect &blit_src_rect = blit_layer->src_rect;
    343     int width = INT(layer->dst_rect.right - layer->dst_rect.left);
    344     int height = INT(layer->dst_rect.bottom - layer->dst_rect.top);
    345     int aligned_w = 0;
    346     int aligned_h = 0;
    347     usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE;
    348     if (blit_engine_c2d_->get(blit_engine_c2d_, COPYBIT_UBWC_SUPPORT) > 0) {
    349       usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
    350     }
    351     // TODO(user): FrameBuffer is assumed to be RGBA
    352     target_width = std::max(target_width, width);
    353     target_height += height;
    354 
    355     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height,
    356                                  INT(HAL_PIXEL_FORMAT_RGBA_8888), usage, aligned_w, aligned_h);
    357 
    358     target_aligned_width = std::max(target_aligned_width, aligned_w);
    359     target_aligned_height += aligned_h;
    360 
    361     // Left will be zero always
    362     dst_rects[processed_blit].top = FLOAT(target_aligned_height - aligned_h);
    363     dst_rects[processed_blit].right = dst_rects[processed_blit].left +
    364                                       (layer->dst_rect.right - layer->dst_rect.left);
    365     dst_rects[processed_blit].bottom = (dst_rects[processed_blit].top +
    366                                       (layer->dst_rect.bottom - layer->dst_rect.top));
    367     blit_src_rect = dst_rects[processed_blit];
    368     processed_blit++;
    369   }
    370 
    371   // Allocate a single buffer of RGBA8888 format
    372   if (blit_needed && (AllocateBlitTargetBuffers(target_width, target_height,
    373                                                 HAL_PIXEL_FORMAT_RGBA_8888, usage) < 0)) {
    374       status = -1;
    375       return status;
    376   }
    377 
    378   if (blit_needed) {
    379     for (uint32_t j = 0; j < num_blit_target_; j++) {
    380       Layer *layer = layer_stack->layers.at(j + content_list->numHwLayers);
    381       private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
    382       // Set the fd information
    383         layer->input_buffer.width = target_aligned_width;
    384         layer->input_buffer.height = target_aligned_height;
    385         layer->input_buffer.unaligned_width = target_width;
    386         layer->input_buffer.unaligned_height = target_height;
    387       if (target_buffer->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    388           layer->input_buffer.format = kFormatRGBA8888Ubwc;
    389       }
    390       layer->input_buffer.planes[0].fd = target_buffer->fd;
    391       layer->input_buffer.planes[0].offset = 0;
    392       layer->input_buffer.planes[0].stride = target_buffer->width;
    393     }
    394   }
    395 
    396   return status;
    397 }
    398 
    399 int BlitEngineC2d::Commit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
    400   int fd = -1;
    401   int status = 0;
    402   bool hybrid_present = false;
    403   uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
    404   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
    405   blit_active_ = false;
    406 
    407   if (!num_app_layers) {
    408     return -1;
    409   }
    410 
    411   // if not Blit Targets return
    412   for (uint32_t i = 0; i < num_app_layers; i++) {
    413     Layer *layer = layer_stack->layers.at(i);
    414     if (layer->composition == kCompositionHybrid || layer->composition == kCompositionBlit) {
    415       hybrid_present = true;
    416     }
    417   }
    418 
    419   if (!hybrid_present) {
    420     return status;
    421   }
    422 
    423   // Clear blit target buffer
    424   LayerRect clear_rect;
    425   clear_rect.left =  0;
    426   clear_rect.top = 0;
    427   clear_rect.right = FLOAT(target_buffer->width);
    428   clear_rect.bottom = FLOAT(target_buffer->height);
    429   ClearTargetBuffer(target_buffer, clear_rect);
    430 
    431   int copybit_layer_count = 0;
    432   uint32_t processed_blit = 0;
    433   for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_) &&
    434       (status == 0); i--) {
    435     Layer *layer = layer_stack->layers.at(i);
    436     if (layer->composition != kCompositionBlit) {
    437       continue;
    438     }
    439 
    440     for (uint32_t k = 0; k <= i; k++) {
    441       Layer *bottom_layer = layer_stack->layers.at(k);
    442       LayerBuffer &layer_buffer = bottom_layer->input_buffer;
    443       // if layer below the blit layer does not intersect, ignore that layer
    444       LayerRect inter_sect = Intersection(layer->dst_rect, bottom_layer->dst_rect);
    445       if (bottom_layer->composition != kCompositionHybrid && !IsValid(inter_sect)) {
    446         continue;
    447       }
    448       if (bottom_layer->composition == kCompositionGPU ||
    449           bottom_layer->composition == kCompositionSDE ||
    450           bottom_layer->composition == kCompositionGPUTarget) {
    451         continue;
    452       }
    453 
    454       // For each layer marked as Hybrid, wait for acquire fence and then blit using the C2D
    455       if (layer_buffer.acquire_fence_fd >= 0) {
    456         // Wait for acquire fence on the App buffers.
    457         if (sync_wait(layer_buffer.acquire_fence_fd, 1000) < 0) {
    458           DLOGE("sync_wait error!! error no = %d err str = %s", errno, strerror(errno));
    459         }
    460         layer_buffer.acquire_fence_fd = -1;
    461       }
    462       hwc_layer_1_t *hwc_layer = &content_list->hwLayers[k];
    463       LayerRect &src_rect = bottom_layer->blit_regions.at(processed_blit);
    464       Layer *blit_layer = layer_stack->layers.at(blit_target_start_index_ + processed_blit);
    465       LayerRect dest_rect = blit_layer->src_rect;
    466       int ret_val = DrawRectUsingCopybit(hwc_layer, bottom_layer, src_rect, dest_rect);
    467       copybit_layer_count++;
    468       if (ret_val < 0) {
    469         copybit_layer_count = 0;
    470         DLOGE("DrawRectUsingCopyBit failed");
    471         status = -1;
    472         break;
    473       }
    474     }
    475     processed_blit++;
    476   }
    477 
    478   if (copybit_layer_count) {
    479     blit_active_ = true;
    480     blit_engine_c2d_->flush_get_fence(blit_engine_c2d_, &fd);
    481   }
    482 
    483   if (blit_active_) {
    484     // dump the render buffer
    485     DumpBlitTargetBuffer(fd);
    486 
    487     // Set the fd to the LayerStack BlitTargets fd
    488     uint32_t layer_count = UINT32(layer_stack->layers.size());
    489     for (uint32_t k = blit_target_start_index_; k < layer_count; k++) {
    490       Layer *layer = layer_stack->layers.at(k);
    491       LayerBuffer &layer_buffer = layer->input_buffer;
    492       layer_buffer.acquire_fence_fd = fd;
    493     }
    494   }
    495 
    496   return status;
    497 }
    498 
    499 int BlitEngineC2d::DrawRectUsingCopybit(hwc_layer_1_t *hwc_layer, Layer *layer,
    500                                         LayerRect blit_rect, LayerRect blit_dest_Rect) {
    501   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
    502   const private_handle_t *hnd = static_cast<const private_handle_t *>(hwc_layer->handle);
    503   LayerBuffer &layer_buffer = layer->input_buffer;
    504 
    505   // Set the Copybit Source
    506   copybit_image_t src;
    507   src.handle = const_cast<native_handle_t *>(hwc_layer->handle);
    508   src.w = hnd->width;
    509   src.h = hnd->height;
    510   src.base = reinterpret_cast<void *>(hnd->base);
    511   src.format = hnd->format;
    512   src.horiz_padding = 0;
    513   src.vert_padding = 0;
    514 
    515   // Copybit source rect
    516   copybit_rect_t src_rect = {INT(blit_rect.left), INT(blit_rect.top), INT(blit_rect.right),
    517                             INT(blit_rect.bottom)};
    518 
    519   // Copybit destination rect
    520   copybit_rect_t dst_rect = {INT(blit_dest_Rect.left), INT(blit_dest_Rect.top),
    521                             INT(blit_dest_Rect.right), INT(blit_dest_Rect.bottom)};
    522 
    523   // Copybit destination buffer
    524   copybit_image_t dst;
    525   dst.handle = static_cast<native_handle_t *>(target_buffer);
    526   dst.w = ALIGN(target_buffer->width, 32);
    527   dst.h = ALIGN((target_buffer->height), 32);
    528   dst.base = reinterpret_cast<void *>(target_buffer->base);
    529   dst.format = target_buffer->format;
    530 
    531   // Copybit region is the destRect
    532   LayerRect region_rect;
    533   region_rect.left = FLOAT(dst_rect.l);
    534   region_rect.top = FLOAT(dst_rect.t);
    535   region_rect.right = FLOAT(dst_rect.r);
    536   region_rect.bottom = FLOAT(dst_rect.b);
    537 
    538   LayerRectArray region;
    539   region.count = 1;
    540   region.rect  = &region_rect;
    541   RegionIterator copybitRegion(region);
    542   int acquireFd = layer_buffer.acquire_fence_fd;
    543 
    544   // FRAMEBUFFER_WIDTH/HEIGHT for c2d is the target buffer w/h
    545   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_WIDTH,
    546                                   target_buffer->width);
    547   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_HEIGHT,
    548                                   target_buffer->height);
    549   int transform = 0;
    550   if (layer->transform.rotation != 0.0f) transform |= COPYBIT_TRANSFORM_ROT_90;
    551   if (layer->transform.flip_horizontal) transform |= COPYBIT_TRANSFORM_FLIP_H;
    552   if (layer->transform.flip_vertical) transform |= COPYBIT_TRANSFORM_FLIP_V;
    553   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_TRANSFORM, transform);
    554   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_PLANE_ALPHA, hwc_layer->planeAlpha);
    555   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_BLEND_MODE, hwc_layer->blending);
    556   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DITHER,
    557     (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
    558 
    559   int src_format_mode = COPYBIT_LINEAR;
    560   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    561     src_format_mode = COPYBIT_UBWC_COMPRESSED;
    562   }
    563   blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_SRC_FORMAT_MODE, src_format_mode);
    564 
    565   blit_engine_c2d_->set_sync(blit_engine_c2d_, acquireFd);
    566   int err = blit_engine_c2d_->stretch(blit_engine_c2d_, &dst, &src, &dst_rect, &src_rect,
    567                                       &copybitRegion);
    568 
    569   if (err < 0) {
    570     DLOGE("copybit stretch failed");
    571   }
    572 
    573   return err;
    574 }
    575 
    576 void BlitEngineC2d::DumpBlitTargetBuffer(int fd) {
    577   if (!dump_frame_count_) {
    578     return;
    579   }
    580 
    581   private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
    582 
    583   if (fd >= 0) {
    584     int error = sync_wait(fd, 1000);
    585     if (error < 0) {
    586       DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
    587       return;
    588     }
    589   }
    590 
    591   char dump_file_name[PATH_MAX];
    592   size_t result = 0;
    593   snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
    594            "/blit_target_%d.raw", (dump_frame_index_));
    595   FILE* fp = fopen(dump_file_name, "w+");
    596   if (fp) {
    597     result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp);
    598     fclose(fp);
    599   }
    600   dump_frame_count_--;
    601   dump_frame_index_++;
    602 }
    603 
    604 }  // namespace sdm
    605 #if defined(__clang__)
    606 #pragma clang diagnostic pop
    607 #endif
    608 
    609