12ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
22ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*
32ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Redistribution and use in source and binary forms, with or without
42ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* modification, are permitted provided that the following conditions are
52ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* met:
62ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*  * Redistributions of source code must retain the above copyright
72ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    notice, this list of conditions and the following disclaimer.
82ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*  * Redistributions in binary form must reproduce the above
92ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    copyright notice, this list of conditions and the following
102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    disclaimer in the documentation and/or other materials provided
112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    with the distribution.
122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*  * Neither the name of The Linux Foundation nor the names of its
132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    contributors may be used to endorse or promote products derived
142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*    from this software without specific prior written permission.
152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*
162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*
172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Portions formerly licensed under Apache License, Version 2.0, are re licensed
302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* under section 4 of Apache License, Version 2.0.
312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Copyright (C) 2010 The Android Open Source Project
332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Not a Contribution.
352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Licensed under the Apache License, Version 2.0 (the "License");
372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* you may not use this file except in compliance with the License.
382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* You may obtain a copy of the License at
392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* http://www.apache.org/licenses/LICENSE-2.0
412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* Unless required by applicable law or agreed to in writing, software
432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* distributed under the License is distributed on an "AS IS" BASIS,
442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* See the License for the specific language governing permissions and
462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel* limitations under the License.
472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel*/
482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <hardware/hardware.h>
502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sync/sync.h>
512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <copybit.h>
522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <memalloc.h>
532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <alloc_controller.h>
542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <gr.h>
552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <utils/constants.h>
572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <utils/rect.h>
582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <utils/formats.h>
592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <algorithm>
602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "blit_engine_c2d.h"
622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "hwc_debugger.h"
632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define __CLASS__ "BlitEngineC2D"
652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// TODO(user): Remove pragma after fixing sign conversion errors
672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#if defined(__clang__)
682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#pragma clang diagnostic push
692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#pragma clang diagnostic ignored "-Wsign-conversion"
702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif
712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelnamespace sdm {
732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBlitEngineC2d::RegionIterator::RegionIterator(LayerRectArray rect) {
762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  rect_array = rect;
772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  r.end = INT(rect.count);
782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  r.current = 0;
792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  this->next = iterate;
802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::RegionIterator::iterate(copybit_region_t const *self, copybit_rect_t *rect) {
832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!self || !rect) {
842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    DLOGE("iterate invalid parameters");
852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return 0;
862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  RegionIterator const *me = static_cast<RegionIterator const*>(self);
892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (me->r.current != me->r.end) {
902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    rect->l = INT(me->rect_array.rect[me->r.current].left);
912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    rect->t = INT(me->rect_array.rect[me->r.current].top);
922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    rect->r = INT(me->rect_array.rect[me->r.current].right);
932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    rect->b = INT(me->rect_array.rect[me->r.current].bottom);
942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    me->r.current++;
952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return 1;
962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return 0;
982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBlitEngineC2d::BlitEngineC2d() {
1012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
1022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_target_buffer_[i] = NULL;
1032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    release_fence_fd_[i] = -1;
1042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBlitEngineC2d::~BlitEngineC2d() {
1082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_engine_c2d_) {
1092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    copybit_close(blit_engine_c2d_);
1102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_engine_c2d_ = NULL;
1112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  FreeBlitTargetBuffers();
1132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::Init() {
1162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hw_module_t const *module;
1172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hw_get_module("copybit", &module) == 0) {
1182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (copybit_open(module, &blit_engine_c2d_) < 0) {
1192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      DLOGI("CopyBitC2D Open failed.");
1202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return -1;
1212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    DLOGI("Opened Copybit Module");
1232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
1242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    DLOGI("Copybit HW Module not found");
1252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -1;
1262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return 0;
1292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::DeInit() {
1322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  FreeBlitTargetBuffers();
1332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_engine_c2d_) {
1342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    copybit_close(blit_engine_c2d_);
1352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_engine_c2d_ = NULL;
1362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format,
1402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                             uint32_t usage) {
1412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int status = 0;
1422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (width <= 0 || height <= 0) {
1432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return false;
1442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_target_buffer_[0]) {
1472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Free and reallocate the buffers if the w/h changes
1482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (INT(width) != blit_target_buffer_[0]->width ||
1492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        INT(height) != blit_target_buffer_[0]->height) {
1502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      FreeBlitTargetBuffers();
1512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
1552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (blit_target_buffer_[i] == NULL) {
1562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      status = alloc_buffer(&blit_target_buffer_[i], width, height, format, usage);
1572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (status < 0) {
1592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      DLOGE("Allocation of Blit target Buffer failed");
1602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      FreeBlitTargetBuffers();
1612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
1622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
1662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::FreeBlitTargetBuffers() {
1692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
1702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    private_handle_t **target_buffer = &blit_target_buffer_[i];
1712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (*target_buffer) {
1722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Free the valid fence
1732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (release_fence_fd_[i] >= 0) {
1742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        close(release_fence_fd_[i]);
1752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        release_fence_fd_[i] = -1;
1762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
1772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      free_buffer(*target_buffer);
1782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *target_buffer = NULL;
1792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::ClearTargetBuffer(private_handle_t* hnd, const LayerRect& rect) {
1842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int status = 0;
1852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_rect_t clear_rect = {INT(rect.left), INT(rect.top), INT(rect.right), INT(rect.bottom)};
1862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_image_t buffer;
1882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  buffer.w = ALIGN((hnd->width), 32);
1892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  buffer.h = hnd->height;
1902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  buffer.format = hnd->format;
1912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  buffer.base = reinterpret_cast<void *>(hnd->base);
1922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  buffer.handle = reinterpret_cast<native_handle_t *>(hnd);
1932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int dst_format_mode = COPYBIT_LINEAR;
1942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    dst_format_mode = COPYBIT_UBWC_COMPRESSED;
1962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DST_FORMAT_MODE, dst_format_mode);
1982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  status = blit_engine_c2d_->clear(blit_engine_c2d_, &buffer, &clear_rect);
2002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
2012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::PostCommit(LayerStack *layer_stack) {
2042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int fence_fd = -1;
2052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t count = 0;
2062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int fd = -1;
2072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = blit_target_start_index_-2; (i > 0) && (count < num_blit_target_); i--) {
2092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(i);
210b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    LayerBuffer &layer_buffer = layer->input_buffer;
2112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (layer->composition == kCompositionBlit) {
2122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int index = blit_target_start_index_ + count;
213b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer_buffer.release_fence_fd =
214b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer_stack->layers.at(index)->input_buffer.release_fence_fd;
215b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      fence_fd = layer_buffer.release_fence_fd;
216b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      close(layer_buffer.acquire_fence_fd);
217b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer_buffer.acquire_fence_fd = -1;
218b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer_stack->layers.at(index)->input_buffer.release_fence_fd = -1;
219b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      fd = layer_stack->layers.at(index)->input_buffer.acquire_fence_fd;
220b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer_stack->layers.at(index)->input_buffer.acquire_fence_fd = -1;
2212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      count++;
2222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (fd >= 0) {
2262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Close the C2D fence FD
2272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    close(fd);
2282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  SetReleaseFence(fence_fd);
2302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// Sync wait to close the previous fd
2332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::SetReleaseFence(int fd) {
2342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (release_fence_fd_[current_blit_target_index_] >= 0) {
2352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    int ret = -1;
2362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ret = sync_wait(release_fence_fd_[current_blit_target_index_], 1000);
2372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (ret < 0) {
2382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      DLOGE("sync_wait error! errno = %d, err str = %s", errno, strerror(errno));
2392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    close(release_fence_fd_[current_blit_target_index_]);
2412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  release_fence_fd_[current_blit_target_index_] = dup(fd);
2432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool BlitEngineC2d::BlitActive() {
2462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return blit_active_;
2472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::SetFrameDumpConfig(uint32_t count) {
2502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dump_frame_count_ = count;
2512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dump_frame_index_ = 0;
2522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::Prepare(LayerStack *layer_stack) {
2552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_target_start_index_ = 0;
2562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t layer_count = UINT32(layer_stack->layers.size());
2582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t gpu_target_index = layer_count - 1;  // default assumption
2592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t i = 0;
2602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (; i < layer_count; i++) {
2622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(i);
2632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // No 10 bit support for C2D
265b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    if (Is10BitFormat(layer->input_buffer.format)) {
2662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return -1;
2672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (layer->composition == kCompositionGPUTarget) {
2702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Need FBT size for allocating buffers
2712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gpu_target_index = i;
2722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((layer_count - 1) == gpu_target_index) {
2772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // No blit target layer
2782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -1;
2792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_target_start_index_ = ++i;
2822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  num_blit_target_ = layer_count - blit_target_start_index_;
2832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
284b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel  LayerBuffer &layer_buffer = layer_stack->layers.at(gpu_target_index)->input_buffer;
285b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel  int fbwidth = INT(layer_buffer.unaligned_width);
286b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel  int fbheight = INT(layer_buffer.unaligned_height);
2872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((fbwidth < 0) || (fbheight < 0)) {
2882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -1;
2892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  current_blit_target_index_ = (current_blit_target_index_ + 1) % kNumBlitTargetBuffers;
2922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int k = blit_target_start_index_;
2932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t j = 0; j < num_blit_target_; j++, k++) {
2952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(k);
296b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    LayerBuffer &layer_buffer = layer->input_buffer;
2973d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    int aligned_w = 0;
2983d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    int aligned_h = 0;
2992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Set the buffer height and width
3013d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(fbwidth, fbheight/3,
3023d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel                   INT(HAL_PIXEL_FORMAT_RGBA_8888), 0, aligned_w, aligned_h);
303b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    layer_buffer.width = aligned_w;
304b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    layer_buffer.height = aligned_h;
305b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    layer_buffer.unaligned_width = fbwidth;
306b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    layer_buffer.unaligned_height = fbheight/3;
3072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    layer->plane_alpha = 0xFF;
3092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    layer->blending = kBlendingOpaque;
3102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    layer->composition = kCompositionBlitTarget;
3112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    layer->frame_rate = layer_stack->layers.at(gpu_target_index)->frame_rate;
3122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return 0;
3152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::PreCommit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
3182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int status = 0;
3192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
3202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int target_width = 0;
3212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int target_height = 0;
3223d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel  int target_aligned_width = 0;
3233d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel  int target_aligned_height = 0;
3242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t processed_blit = 0;
3252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  LayerRect dst_rects[kMaxBlitTargetLayers];
3262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool blit_needed = false;
3272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t usage = 0;
3282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!num_app_layers) {
3302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -1;
3312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_); i--) {
3342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(i);
3352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (layer->composition != kCompositionBlit) {
3362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      continue;
3372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_needed = true;
3392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    layer_stack->flags.attributes_changed = true;
3402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *blit_layer = layer_stack->layers.at(blit_target_start_index_ + processed_blit);
3422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    LayerRect &blit_src_rect = blit_layer->src_rect;
3432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    int width = INT(layer->dst_rect.right - layer->dst_rect.left);
3442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    int height = INT(layer->dst_rect.bottom - layer->dst_rect.top);
3453d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    int aligned_w = 0;
3463d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    int aligned_h = 0;
3472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE;
3482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (blit_engine_c2d_->get(blit_engine_c2d_, COPYBIT_UBWC_SUPPORT) > 0) {
3492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
3502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // TODO(user): FrameBuffer is assumed to be RGBA
3522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    target_width = std::max(target_width, width);
3532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    target_height += height;
3542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3553d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height,
3563d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel                                 INT(HAL_PIXEL_FORMAT_RGBA_8888), usage, aligned_w, aligned_h);
3573d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel
3583d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    target_aligned_width = std::max(target_aligned_width, aligned_w);
3593d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    target_aligned_height += aligned_h;
3603d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel
3612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Left will be zero always
3623d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    dst_rects[processed_blit].top = FLOAT(target_aligned_height - aligned_h);
3632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    dst_rects[processed_blit].right = dst_rects[processed_blit].left +
3642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                      (layer->dst_rect.right - layer->dst_rect.left);
3652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    dst_rects[processed_blit].bottom = (dst_rects[processed_blit].top +
3662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                      (layer->dst_rect.bottom - layer->dst_rect.top));
3672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_src_rect = dst_rects[processed_blit];
3682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    processed_blit++;
3692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allocate a single buffer of RGBA8888 format
3722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_needed && (AllocateBlitTargetBuffers(target_width, target_height,
3732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                                HAL_PIXEL_FORMAT_RGBA_8888, usage) < 0)) {
3742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      status = -1;
3752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return status;
3762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_needed) {
3792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (uint32_t j = 0; j < num_blit_target_; j++) {
3802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      Layer *layer = layer_stack->layers.at(j + content_list->numHwLayers);
3812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
3822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Set the fd information
383b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer->input_buffer.width = target_aligned_width;
384b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer->input_buffer.height = target_aligned_height;
385b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer->input_buffer.unaligned_width = target_width;
386b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer->input_buffer.unaligned_height = target_height;
3872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (target_buffer->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
388b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel          layer->input_buffer.format = kFormatRGBA8888Ubwc;
3892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
390b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer->input_buffer.planes[0].fd = target_buffer->fd;
391b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer->input_buffer.planes[0].offset = 0;
392b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer->input_buffer.planes[0].stride = target_buffer->width;
3932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
3972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::Commit(hwc_display_contents_1_t *content_list, LayerStack *layer_stack) {
4002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int fd = -1;
4012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int status = 0;
4022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool hybrid_present = false;
4032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t num_app_layers = (uint32_t) content_list->numHwLayers-1;
4042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
4052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_active_ = false;
4062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!num_app_layers) {
4082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -1;
4092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // if not Blit Targets return
4122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = 0; i < num_app_layers; i++) {
4132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(i);
4142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (layer->composition == kCompositionHybrid || layer->composition == kCompositionBlit) {
4152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      hybrid_present = true;
4162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
4172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!hybrid_present) {
4202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return status;
4212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Clear blit target buffer
4242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  LayerRect clear_rect;
4252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  clear_rect.left =  0;
4262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  clear_rect.top = 0;
4272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  clear_rect.right = FLOAT(target_buffer->width);
4282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  clear_rect.bottom = FLOAT(target_buffer->height);
4292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ClearTargetBuffer(target_buffer, clear_rect);
4302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int copybit_layer_count = 0;
4322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t processed_blit = 0;
4332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_) &&
4342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (status == 0); i--) {
4352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    Layer *layer = layer_stack->layers.at(i);
4362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (layer->composition != kCompositionBlit) {
4372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      continue;
4382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
4392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (uint32_t k = 0; k <= i; k++) {
4412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      Layer *bottom_layer = layer_stack->layers.at(k);
442b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      LayerBuffer &layer_buffer = bottom_layer->input_buffer;
4432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // if layer below the blit layer does not intersect, ignore that layer
4442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      LayerRect inter_sect = Intersection(layer->dst_rect, bottom_layer->dst_rect);
4452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (bottom_layer->composition != kCompositionHybrid && !IsValid(inter_sect)) {
4462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        continue;
4472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
4482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (bottom_layer->composition == kCompositionGPU ||
4492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          bottom_layer->composition == kCompositionSDE ||
4502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          bottom_layer->composition == kCompositionGPUTarget) {
4512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        continue;
4522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
4532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // For each layer marked as Hybrid, wait for acquire fence and then blit using the C2D
455b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      if (layer_buffer.acquire_fence_fd >= 0) {
4562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        // Wait for acquire fence on the App buffers.
457b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        if (sync_wait(layer_buffer.acquire_fence_fd, 1000) < 0) {
4582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          DLOGE("sync_wait error!! error no = %d err str = %s", errno, strerror(errno));
4592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        }
460b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel        layer_buffer.acquire_fence_fd = -1;
4612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
4622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      hwc_layer_1_t *hwc_layer = &content_list->hwLayers[k];
4632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      LayerRect &src_rect = bottom_layer->blit_regions.at(processed_blit);
4642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      Layer *blit_layer = layer_stack->layers.at(blit_target_start_index_ + processed_blit);
4652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      LayerRect dest_rect = blit_layer->src_rect;
4662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int ret_val = DrawRectUsingCopybit(hwc_layer, bottom_layer, src_rect, dest_rect);
4672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      copybit_layer_count++;
4682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (ret_val < 0) {
4692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        copybit_layer_count = 0;
4702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        DLOGE("DrawRectUsingCopyBit failed");
4712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        status = -1;
4722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        break;
4732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
4742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
4752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    processed_blit++;
4762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (copybit_layer_count) {
4792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_active_ = true;
4802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    blit_engine_c2d_->flush_get_fence(blit_engine_c2d_, &fd);
4812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (blit_active_) {
4842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // dump the render buffer
4852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    DumpBlitTargetBuffer(fd);
4862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Set the fd to the LayerStack BlitTargets fd
4882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    uint32_t layer_count = UINT32(layer_stack->layers.size());
4892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (uint32_t k = blit_target_start_index_; k < layer_count; k++) {
4902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      Layer *layer = layer_stack->layers.at(k);
491b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      LayerBuffer &layer_buffer = layer->input_buffer;
492b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      layer_buffer.acquire_fence_fd = fd;
4932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
4942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
4972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BlitEngineC2d::DrawRectUsingCopybit(hwc_layer_1_t *hwc_layer, Layer *layer,
5002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                        LayerRect blit_rect, LayerRect blit_dest_Rect) {
5012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
5022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  const private_handle_t *hnd = static_cast<const private_handle_t *>(hwc_layer->handle);
503b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel  LayerBuffer &layer_buffer = layer->input_buffer;
5042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Set the Copybit Source
5062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_image_t src;
5072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.handle = const_cast<native_handle_t *>(hwc_layer->handle);
5082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.w = hnd->width;
5092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.h = hnd->height;
5102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.base = reinterpret_cast<void *>(hnd->base);
5112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.format = hnd->format;
5122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.horiz_padding = 0;
5132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  src.vert_padding = 0;
5142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Copybit source rect
5162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_rect_t src_rect = {INT(blit_rect.left), INT(blit_rect.top), INT(blit_rect.right),
5172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            INT(blit_rect.bottom)};
5182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Copybit destination rect
5202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_rect_t dst_rect = {INT(blit_dest_Rect.left), INT(blit_dest_Rect.top),
5212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            INT(blit_dest_Rect.right), INT(blit_dest_Rect.bottom)};
5222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Copybit destination buffer
5242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  copybit_image_t dst;
5252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dst.handle = static_cast<native_handle_t *>(target_buffer);
5262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dst.w = ALIGN(target_buffer->width, 32);
5272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dst.h = ALIGN((target_buffer->height), 32);
5282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dst.base = reinterpret_cast<void *>(target_buffer->base);
5292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dst.format = target_buffer->format;
5302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Copybit region is the destRect
5322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  LayerRect region_rect;
5332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region_rect.left = FLOAT(dst_rect.l);
5342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region_rect.top = FLOAT(dst_rect.t);
5352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region_rect.right = FLOAT(dst_rect.r);
5362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region_rect.bottom = FLOAT(dst_rect.b);
5372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  LayerRectArray region;
5392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region.count = 1;
5402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  region.rect  = &region_rect;
5412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  RegionIterator copybitRegion(region);
542b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel  int acquireFd = layer_buffer.acquire_fence_fd;
5432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // FRAMEBUFFER_WIDTH/HEIGHT for c2d is the target buffer w/h
5452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_WIDTH,
5462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  target_buffer->width);
5472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_FRAMEBUFFER_HEIGHT,
5482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  target_buffer->height);
5492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int transform = 0;
5502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (layer->transform.rotation != 0.0f) transform |= COPYBIT_TRANSFORM_ROT_90;
5512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (layer->transform.flip_horizontal) transform |= COPYBIT_TRANSFORM_FLIP_H;
5522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (layer->transform.flip_vertical) transform |= COPYBIT_TRANSFORM_FLIP_V;
5532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_TRANSFORM, transform);
5542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_PLANE_ALPHA, hwc_layer->planeAlpha);
5552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_BLEND_MODE, hwc_layer->blending);
5562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DITHER,
5572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
5582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int src_format_mode = COPYBIT_LINEAR;
5602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
5612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    src_format_mode = COPYBIT_UBWC_COMPRESSED;
5622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_SRC_FORMAT_MODE, src_format_mode);
5642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  blit_engine_c2d_->set_sync(blit_engine_c2d_, acquireFd);
5662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = blit_engine_c2d_->stretch(blit_engine_c2d_, &dst, &src, &dst_rect, &src_rect,
5672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                      &copybitRegion);
5682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (err < 0) {
5702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    DLOGE("copybit stretch failed");
5712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
5742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
5752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BlitEngineC2d::DumpBlitTargetBuffer(int fd) {
5772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!dump_frame_count_) {
5782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return;
5792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *target_buffer = blit_target_buffer_[current_blit_target_index_];
5822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (fd >= 0) {
5842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    int error = sync_wait(fd, 1000);
5852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (error < 0) {
5862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      DLOGW("sync_wait error errno = %d, desc = %s", errno, strerror(errno));
5872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return;
5882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
5892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  char dump_file_name[PATH_MAX];
5922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size_t result = 0;
5932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  snprintf(dump_file_name, sizeof(dump_file_name), "/data/misc/display/frame_dump_primary"
5942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel           "/blit_target_%d.raw", (dump_frame_index_));
5952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  FILE* fp = fopen(dump_file_name, "w+");
5962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (fp) {
5972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    result = fwrite(reinterpret_cast<void *>(target_buffer->base), target_buffer->size, 1, fp);
5982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    fclose(fp);
5992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dump_frame_count_--;
6012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  dump_frame_index_++;
6022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}  // namespace sdm
6052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#if defined(__clang__)
6062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#pragma clang diagnostic pop
6072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif
6082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
609