android13/hardware/rockchip/hwcomposer/drmhwc2/resources/resourcemanager.cpp

732 lines
24 KiB
C++
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "hwc-resource-manager"
#include "resources/resourcemanager.h"
#include "drmlayer.h"
#include <cutils/properties.h>
#include <log/log.h>
#include <sstream>
#include <string>
#include <drm_fourcc.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <utils/Trace.h>
#include <rga.h>
//XML prase
#include <tinyxml2.h>
namespace android {
#define hwcMIN(x, y) (((x) <= (y)) ? (x) : (y))
#define hwcMAX(x, y) (((x) >= (y)) ? (x) : (y))
#ifndef IS_ALIGN
#define IS_ALIGN(val, align) (((val) & (align - 1)) == 0)
#endif
#ifndef ALIGN
#define ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
#endif
#ifndef ALIGN_DOWN
#define ALIGN_DOWN(value, base) (value & (~(base - 1)))
#endif
// define from hardware/rockchip/libgralloc/bifrost/src/mali_gralloc_usages.h
#ifndef RK_GRALLOC_USAGE_WITHIN_4G
#define RK_GRALLOC_USAGE_WITHIN_4G (1ULL << 56)
#endif
#ifndef RK_GRALLOC_USAGE_STRIDE_ALIGN_16
#define RK_GRALLOC_USAGE_STRIDE_ALIGN_16 (1ULL << 57)
#endif
/* Gralloc 4.0 中, 表征 "调用 alloc() 的 client 要求分配的 buffer 不是 AFBC 格式".
*/
#ifndef MALI_GRALLOC_USAGE_NO_AFBC
#define MALI_GRALLOC_USAGE_NO_AFBC (1ULL << 29)
#endif
#define WB_BUFFERQUEUE_MAX_SIZE 4
ResourceManager::ResourceManager() :
num_displays_(0) {
drmGralloc_ = DrmGralloc::getInstance();
}
int ResourceManager::Init(DrmHwcTwo *hwc2) {
hwc2_ = hwc2;
int ret = AddDrmDevice();
if(ret){
ALOGE("Failed to AddDrmDevice ");
}
if (!num_displays_) {
ALOGE("Failed to initialize any displays");
return ret ? -EINVAL : ret;
}
fb0_fd = open("/dev/graphics/fb0", O_RDWR, 0);
if(fb0_fd < 0){
ALOGE("Open fb0 fail in %s",__FUNCTION__);
}
DrmDevice *drm = drms_.front().get();
for(auto &crtc : drm->crtcs()){
mapDrmDisplayCompositor_.insert(
std::pair<int, std::shared_ptr<DrmDisplayCompositor>>(crtc->id(),std::make_shared<DrmDisplayCompositor>()));
HWC2_ALOGI("Create DrmDisplayCompositor crtc=%d",crtc->id());
}
displays_ = drm->GetDisplays();
if(displays_.size() == 0){
ALOGE("Failed to initialize any displays");
return ret ? -EINVAL : ret;
}
// 更新全局平台版本信息
gSetSocId(drm->getSocId());
// 更新全局 kernel drm 版本信息
gSetDrmVersion(drm->getDrmVersion());
// 更新配置
InitProperty();
return 0;
}
int ResourceManager::AddDrmDevice() {
std::unique_ptr<DrmDevice> drm = std::make_unique<DrmDevice>();
int displays_added, ret;
std::tie(ret, displays_added) = drm->Init(num_displays_);
if (ret < 0)
return ret;
//Get soc id
soc_id_ = drm->getSocId();
//DrmVersion
drmVersion_ = drm->getDrmVersion();
drmGralloc_->set_drm_version(dup(drm->fd()),drmVersion_);
std::shared_ptr<Importer> importer;
importer.reset(Importer::CreateInstance(drm.get()));
if (!importer) {
ALOGE("Failed to create importer instance");
return -ENODEV;
}
importers_.push_back(std::move(importer));
drms_.push_back(std::move(drm));
num_displays_ += displays_added;
return ret;
}
DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
DrmDevice *drm_device = GetDrmDevice(display);
DrmConnector *writeback_conn = NULL;
if (drm_device) {
writeback_conn = drm_device->AvailableWritebackConnector(display);
if (writeback_conn)
return writeback_conn;
}
for (auto &drm : drms_) {
if (drm.get() == drm_device)
continue;
writeback_conn = drm->AvailableWritebackConnector(display);
if (writeback_conn)
return writeback_conn;
}
return writeback_conn;
}
int ResourceManager::InitProperty() {
char property_value[PROPERTY_VALUE_MAX];
property_get("vendor.hwc.enable_composition_drop_mode", property_value, "0");
mCompositionDropMode_ = atoi(property_value) != 0;
property_get("vendor.hwc.enable_dynamic_display_mode", property_value, "0");
mDynamicDisplayMode_ = atoi(property_value) > 0;
property_get("vendor.hwc.enable_sideband_stream_2_mode", property_value, "0");
mSidebandStream2Mode_ = atoi(property_value) > 0;
property_get("vendor.hwc.video_buf_cache_max_size", property_value, "0");
mCacheBufferLimitSize_ = atoi(property_value);
return 0;
}
bool ResourceManager::IsCompositionDropMode() const {
return mCompositionDropMode_;
}
bool ResourceManager::IsDynamicDisplayMode() const {
return mDynamicDisplayMode_;
}
bool ResourceManager::IsSidebandStream2Mode() const {
// RK3528 默认开启 Sideband2.0支持
if(gIsRK3528()){
return true;
}
return mSidebandStream2Mode_;
}
int ResourceManager::GetCacheBufferLimitSize() const{
return mCacheBufferLimitSize_;
}
DrmDevice *ResourceManager::GetDrmDevice(int display) {
for (auto &drm : drms_) {
if (drm->HandlesDisplay(display & ~DRM_CONNECTOR_SPILT_MODE_MASK))
return drm.get();
}
return NULL;
}
std::shared_ptr<Importer> ResourceManager::GetImporter(int display) {
for (unsigned int i = 0; i < drms_.size(); i++) {
if (drms_[i]->HandlesDisplay(display & ~DRM_CONNECTOR_SPILT_MODE_MASK))
return importers_[i];
}
return NULL;
}
std::shared_ptr<DrmDisplayCompositor> ResourceManager::GetDrmDisplayCompositor(DrmCrtc* crtc){
if(!crtc){
HWC2_ALOGE("crtc is null");
return NULL;
}
if(mapDrmDisplayCompositor_.size() == 0){
HWC2_ALOGE("mapDrmDisplayCompositor_.size()=0");
return NULL;
}
auto pairDrmDisplayCompositor = mapDrmDisplayCompositor_.find(crtc->id());
return pairDrmDisplayCompositor->second;
}
int ResourceManager::GetWBDisplay() const {
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return iWriteBackDisplayId_;
}
bool ResourceManager::isWBMode() const {
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return bEnableWriteBackRef_ > 0;
}
const DrmMode& ResourceManager::GetWBMode() const {
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mWBMode_;
}
bool ResourceManager::IsDisableHwVirtualDisplay(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mVDMode_ == HWC2_DISABLE_HW_VIRTUAL_DISPLAY;
}
bool ResourceManager::IsWriteBackByVop(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mVDMode_ == HWC2_HW_VIRTUAL_DISPLAY_USE_VOP;
}
bool ResourceManager::IsWriteBackByRga(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mVDMode_ == HWC2_HW_VIRTUAL_DISPLAY_USE_RGA;
}
HwVirtualDisplayMode_t ResourceManager::ChooseWriteBackMode(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
// 2. 获取待 WriteBack display状态状态异常则直接关闭 WriteBack 模式
DrmDevice *drmDevice = GetDrmDevice(display);
DrmConnector *writeBackConn = drmDevice->GetConnectorForDisplay(display);
if(!writeBackConn){
HWC2_ALOGE("display=%d WriteBackConn is NULL", display);
return HWC2_DISABLE_HW_VIRTUAL_DISPLAY;
}
if(writeBackConn->state() != DRM_MODE_CONNECTED){
HWC2_ALOGE("display=%d WriteBackConn state isn't connected(%d)",
display, writeBackConn->state());
return HWC2_DISABLE_HW_VIRTUAL_DISPLAY;
}
// 3. 获取待 WriteBack 当前分辨率,用于申请 WriteBackBuffer
// 4. WriteBack 硬件要求 16对齐否则超出部分会直接丢弃
mWBMode_ = writeBackConn->current_mode();
if(mWBMode_.width() > 4096 || mWBMode_.height() > 2160){
HWC2_ALOGI("Primary resolution=%dx%d, use WriteBack by RGA", mWBMode_.width(), mWBMode_.height());
return HWC2_HW_VIRTUAL_DISPLAY_USE_RGA;
}
HWC2_ALOGI("Primary resolution=%dx%d, use WriteBack by Vop WriteBack", mWBMode_.width(), mWBMode_.height());
return HWC2_HW_VIRTUAL_DISPLAY_USE_VOP;
}
// 使用 Vop 作为 WriteBack 内容输出单元
int ResourceManager::WriteBackUseVop(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
iWBWidth_ = ALIGN_DOWN(mWBMode_.width(),16);
iWBHeight_ = mWBMode_.height();
iWBFormat_ = HAL_PIXEL_FORMAT_YCrCb_NV12;
// 5. 创建 WriteBackBuffer BufferQueue并且申请 WB Buffer.
if(mWriteBackBQ_ == NULL){
mWriteBackBQ_ = std::make_shared<DrmBufferQueue>(WB_BUFFERQUEUE_MAX_SIZE);
mNextWriteBackBuffer_
= mWriteBackBQ_->DequeueDrmBuffer(iWBWidth_,
iWBHeight_,
iWBFormat_,
RK_GRALLOC_USAGE_STRIDE_ALIGN_16 |
MALI_GRALLOC_USAGE_NO_AFBC,
"WriteBackBuffer");
if(!mNextWriteBackBuffer_->initCheck()){
HWC2_ALOGE("display=%d WBBuffer Dequeue fail, w=%d h=%d format=%d",
display,
iWBWidth_,
iWBHeight_,
iWBFormat_);
return -1;
}
}
bEnableWriteBackRef_++;
iWriteBackDisplayId_ = display;
return 0;
}
// 使用 Rga 作为 WriteBack 内容输出单元
int ResourceManager::WriteBackUseRga(int display){
// 利用 RGA 进行 WriteBack, RGA alpha blend 要求点对点,不允许缩放
// 故要求申请内存与系统UI分辨率一致
if(hwc2_->GetDisplayCtxPtr(display) != NULL){
hwc2_drm_display_t* dpy_ctx = hwc2_->GetDisplayCtxPtr(display);
iWBWidth_ = dpy_ctx->framebuffer_width;
iWBHeight_ = dpy_ctx->framebuffer_height;
iWBFormat_ = HAL_PIXEL_FORMAT_RGBA_8888;
}else{
iWBWidth_ = mWBMode_.h_display();
iWBHeight_ = mWBMode_.v_display();
iWBFormat_ = HAL_PIXEL_FORMAT_RGBA_8888;
}
// 5. 创建 WriteBackBuffer BufferQueue并且申请 WB Buffer.
if(mWriteBackBQ_ == NULL){
mWriteBackBQ_ = std::make_shared<DrmBufferQueue>();
mNextWriteBackBuffer_
= mWriteBackBQ_->DequeueDrmBuffer(iWBWidth_,
iWBHeight_,
iWBFormat_,
RK_GRALLOC_USAGE_STRIDE_ALIGN_16 |
MALI_GRALLOC_USAGE_NO_AFBC,
"WriteBackBuffer");
if(!mNextWriteBackBuffer_->initCheck()){
HWC2_ALOGE("display=%d WBBuffer Dequeue fail, w=%d h=%d format=%d",
display,
iWBWidth_,
iWBHeight_,
iWBFormat_);
return -1;
}
}
bEnableWriteBackRef_++;
iWriteBackDisplayId_ = display;
return 0;
}
int ResourceManager::EnableWriteBackMode(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
// 1. 检查 WB 模块是否已经被绑定
if(bEnableWriteBackRef_ > 0){
if(iWriteBackDisplayId_ != display){
HWC2_ALOGE("WriteBack has bind display %d, so display=%d WB request can't handle.",
iWriteBackDisplayId_, display);
return -1;
}else{
bEnableWriteBackRef_++;
return 0;
}
}
// 2. 根据 primary 分辨率模式选择 WriteBack 模式
mVDMode_ = ChooseWriteBackMode(display);
switch(mVDMode_){
case HWC2_HW_VIRTUAL_DISPLAY_USE_VOP:
return WriteBackUseVop(display);
case HWC2_HW_VIRTUAL_DISPLAY_USE_RGA:
return WriteBackUseRga(display);
case HWC2_DISABLE_HW_VIRTUAL_DISPLAY:
default:
HWC2_ALOGE("display=%d can't find any suitable WriteBack mode, roll back to GLES display, VDMode=%d",
display, mVDMode_);
return -1;
}
return -1;
}
int ResourceManager::UpdateWriteBackResolutionUseVop(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
// 2. 获取待 WriteBack display状态状态异常则直接关闭 WriteBack 模式
DrmDevice *drmDevice = GetDrmDevice(display);
DrmConnector *writeBackConn = drmDevice->GetConnectorForDisplay(display);
if(!writeBackConn){
HWC2_ALOGE("display=%d WriteBackConn is NULL", display);
return -1;
}
if(writeBackConn->state() != DRM_MODE_CONNECTED){
HWC2_ALOGE("display=%d WriteBackConn state isn't connected(%d)",
display, writeBackConn->state());
return -1;
}
// 3. 获取待 WriteBack 当前分辨率,用于申请 WriteBackBuffer
DrmMode currentMode = writeBackConn->current_mode();
mWBMode_ = currentMode;
int tempWBWidth = ALIGN_DOWN(mWBMode_.width(),16);
int tempWBHeight = mWBMode_.height();
if(tempWBWidth == iWBWidth_ &&
tempWBHeight == iWBHeight_){
return 0;
}else{
HWC2_ALOGI("display=%d update WriteBack resolution(%dx%d)=>(%dx%d)",
display, iWBWidth_, iWBHeight_,
currentMode.width(), currentMode.height());
}
iWBWidth_ = tempWBWidth;
iWBHeight_ = tempWBHeight;
iWBFormat_ = HAL_PIXEL_FORMAT_YCrCb_NV12;
// 4. 创建 WriteBackBuffer BufferQueue并且申请 WB Buffer.
if(mWriteBackBQ_ == NULL){
mWriteBackBQ_ = std::make_shared<DrmBufferQueue>(WB_BUFFERQUEUE_MAX_SIZE);
}
mNextWriteBackBuffer_
= mWriteBackBQ_->DequeueDrmBuffer(iWBWidth_,
iWBHeight_,
iWBFormat_,
RK_GRALLOC_USAGE_STRIDE_ALIGN_16 |
MALI_GRALLOC_USAGE_NO_AFBC,
"WriteBackBuffer");
if(!mNextWriteBackBuffer_->initCheck()){
HWC2_ALOGE("display=%d WBBuffer Dequeue fail, w=%d h=%d format=%d",
display, iWBWidth_, iWBHeight_, iWBFormat_);
return -1;
}
return 0;
}
int ResourceManager::UpdateWriteBackResolution(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
// 1. 检查 WB 模块是否已经被绑定
if(bEnableWriteBackRef_ > 0){
if(iWriteBackDisplayId_ != display){
HWC2_ALOGE("WriteBack has bind display %d, so display=%d WB request can't handle.",
iWriteBackDisplayId_, display);
return -1;
}
}
// 根据 WriteBack mode 处理 update WriteBack resolution 请求
switch(mVDMode_){
case HWC2_HW_VIRTUAL_DISPLAY_USE_VOP:
return UpdateWriteBackResolutionUseVop(display);
case HWC2_HW_VIRTUAL_DISPLAY_USE_RGA:
// RGA 模式不需要考虑分辨率切换的场景
return 0;
case HWC2_DISABLE_HW_VIRTUAL_DISPLAY:
default:
HWC2_ALOGE("display=%d can't find any suitable WriteBack mode, VDMode=%d ", display, mVDMode_);
return -1;
}
return 0;
}
int ResourceManager::DisableWriteBackMode(int display){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
if(display != iWriteBackDisplayId_)
return 0;
bEnableWriteBackRef_--;
if(bEnableWriteBackRef_ <= 0){
iWriteBackDisplayId_ = -1;
mFinishBufferQueue_.clear();
mVDMode_ = HWC2_DISABLE_HW_VIRTUAL_DISPLAY;
}
return 0;
}
std::shared_ptr<DrmBuffer> ResourceManager::GetResetWBBuffer(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
if(mResetBackBuffer_ == NULL){
mResetBackBuffer_ = std::make_shared<DrmBuffer>(640,
360,
HAL_PIXEL_FORMAT_YCrCb_NV12,
RK_GRALLOC_USAGE_STRIDE_ALIGN_16 |
RK_GRALLOC_USAGE_WITHIN_4G,
"WBResetBuffer");
if(mResetBackBuffer_->Init()){
HWC2_ALOGE("DrmBuffer Init fail, w=%d h=%d format=%d name=%s",
640, 360, HAL_PIXEL_FORMAT_YCrCb_NV12, "WBResetBuffer");
mResetBackBuffer_ = NULL;
return NULL;
}
rga_buffer_t src;
im_rect src_rect;
memset(&src, 0x0, sizeof(rga_buffer_t));
memset(&src_rect, 0x0, sizeof(im_rect));
// Set src buffer info
src.fd = mResetBackBuffer_->GetFd();
src.width = mResetBackBuffer_->GetWidth();
src.height = mResetBackBuffer_->GetHeight();
src.wstride = mResetBackBuffer_->GetStride();
src.hstride = mResetBackBuffer_->GetHeightStride();
src.format = mResetBackBuffer_->GetFormat();
// Set src rect info
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = src.width ;
src_rect.height = src.height;
src.color_space_mode = IM_RGB_TO_YUV_BT601_LIMIT;
// Set Dataspace
// if((buffer.mBufferInfo_.uDataSpace_ & HAL_DATASPACE_STANDARD_BT709) == HAL_DATASPACE_STANDARD_BT709){
// dst.color_space_mode = IM_YUV_TO_RGB_BT709_LIMIT;
// SVEP_ALOGD_IF("color_space_mode = BT709 dataspace=0x%" PRIx64,buffer.mBufferInfo_.uDataSpace_);
// }else{
// SVEP_ALOGD_IF("color_space_mode = BT601 dataspace=0x%" PRIx64,buffer.mBufferInfo_.uDataSpace_);
// }
IM_STATUS im_state;
// Call Im2d 格式转换
im_state = imfill(src, src_rect, 0x0);
if(im_state != IM_STATUS_SUCCESS){
HWC2_ALOGE("call im2d reset Fail!");
}
}
return mResetBackBuffer_;
}
std::shared_ptr<DrmBuffer> ResourceManager::GetNextWBBuffer(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mNextWriteBackBuffer_;
}
std::shared_ptr<DrmBuffer> ResourceManager::GetDrawingWBBuffer(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mDrawingWriteBackBuffer_;;
}
int ResourceManager::GetFinishWBBufferSize(){
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
return mFinishBufferQueue_.size();
}
int ResourceManager::OutputWBBuffer(int display_id,
rga_buffer_t &dst,
im_rect &dst_rect,
int32_t *retire_fence,
uint64_t *last_frame_no){
ATRACE_CALL();
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
if(mFinishBufferQueue_.size() == 0){
HWC2_ALOGE("mFinishBufferQueue_ size is 0");
return -1;
}
std::shared_ptr<DrmBuffer> output_buffer = NULL;
uint64_t output_frame_no = 0;
std::queue<PAIR_ID_BUFFER> tmp_bufferqueue;
for(auto &FinishBufferPair : mFinishBufferQueue_){
if(FinishBufferPair.first > *last_frame_no){
output_buffer = FinishBufferPair.second;
output_frame_no = FinishBufferPair.first;
break;
}
}
if(output_buffer == NULL && mFinishBufferQueue_.size() >0){
output_buffer = mFinishBufferQueue_.back().second;
output_frame_no = mFinishBufferQueue_.back().first;
HWC2_ALOGW("VDS may output a same image frame_no=%" PRIu64 " Last_frame_no=%" PRIu64 , output_frame_no, *last_frame_no);
}
if(output_buffer == NULL){
HWC2_ALOGE("output_buffer is NULL");
return -1;
}
HWC2_ALOGD_IF_DEBUG("WB: display=%d frame_no=%" PRIu64 " id=%" PRIu64 " queue.size=%zu" ,
display_id, output_frame_no, output_buffer->GetId(),mFinishBufferQueue_.size());
output_buffer->WaitFinishFence();
// 添加调试接口抓打印WriteBack Buffer
char value[PROPERTY_VALUE_MAX];
property_get("debug.wb.dump", value, "0");
if(atoi(value) > 0){
output_buffer->DumpData();
}
rga_buffer_t src;
rga_buffer_t pat;
im_rect src_rect;
im_rect pat_rect;
memset(&src, 0x0, sizeof(rga_buffer_t));
memset(&pat, 0x0, sizeof(rga_buffer_t));
memset(&src_rect, 0x0, sizeof(im_rect));
memset(&src_rect, 0x0, sizeof(im_rect));
// Set src buffer info
src.fd = output_buffer->GetFd();
src.width = output_buffer->GetWidth();
src.height = output_buffer->GetHeight();
src.wstride = output_buffer->GetStride();
src.hstride = output_buffer->GetHeightStride();
src.format = output_buffer->GetFormat();
// 由于WriteBack仅支持BGR888(B:G:R little endian)故需要使用RGA做格式转换
if(src.format == HAL_PIXEL_FORMAT_RGB_888)
src.format = RK_FORMAT_BGR_888;
// 由于WriteBack仅支持BGR565(B:G:R little endian)故需要使用RGA做格式转换
if(src.format == HAL_PIXEL_FORMAT_RGB_565)
src.format = RK_FORMAT_BGR_565;
// Set src rect info
src_rect.x = 0;
src_rect.y = 0;
src_rect.width = output_buffer->GetWidth();
src_rect.height = output_buffer->GetHeight();
// Set Dataspace
// if((srcBuffer.mBufferInfo_.uDataSpace_ & HAL_DATASPACE_STANDARD_BT709) == HAL_DATASPACE_STANDARD_BT709){
// dst.color_space_mode = IM_YUV_TO_RGB_BT709_LIMIT;
// SVEP_ALOGD_IF("color_space_mode = BT709 dataspace=0x%" PRIx64,srcBuffer.mBufferInfo_.uDataSpace_);
// }else{
// SVEP_ALOGD_IF("color_space_mode = BT601 dataspace=0x%" PRIx64,srcBuffer.mBufferInfo_.uDataSpace_);
// }
IM_STATUS im_state;
im_opt_t imOpt;
memset(&imOpt, 0x00, sizeof(im_opt_t));
imOpt.core = IM_SCHEDULER_RGA3_CORE0 | IM_SCHEDULER_RGA3_CORE1;
// Call Im2d 格式转换
im_state = improcess(src, dst, pat, src_rect, dst_rect, pat_rect, 0, NULL, &imOpt, IM_SYNC);
if(im_state == IM_STATUS_SUCCESS){
HWC2_ALOGD_IF_VERBOSE("call im2d convert to rgb888 Success");
*retire_fence = -1;
}else{
HWC2_ALOGD_IF_DEBUG("call im2d fail, ret=%d Error=%s", im_state, imStrError(im_state));
*retire_fence = -1;
return -1;
}
*last_frame_no = output_frame_no;
return 0;
}
int ResourceManager::SwapWBBuffer(uint64_t frame_no){
ATRACE_CALL();
std::unique_lock<std::recursive_mutex> lock(mRecursiveMutex);
if(bEnableWriteBackRef_ <= 0){
HWC2_ALOGE("");
return -1;
}
// 1. Drawing 切换为 Finish 状态, 并 push 进队列
if(mDrawingWriteBackBuffer_ != NULL){
mFinishBufferQueue_.push_back(PAIR_ID_BUFFER{frame_no, mDrawingWriteBackBuffer_});
HWC2_ALOGD_IF_VERBOSE("WB: frame_no=%" PRIu64 " id=%" PRIu64 " queue.size=%zu" ,frame_no, mDrawingWriteBackBuffer_->GetId(),mFinishBufferQueue_.size());
// 环形缓冲区,若达到环形缓冲区最大尺寸,则需要丢掉最旧的一帧缓存
if(mFinishBufferQueue_.size() > (WB_BUFFERQUEUE_MAX_SIZE - 1)){
auto last_buffer_pair = mFinishBufferQueue_.begin();
mFinishBufferQueue_.erase(last_buffer_pair);
HWC2_ALOGD_IF_WARN("WB: lost frame_no=%" PRIu64 " id=%" PRIu64 " queue.size=%zu" ,
last_buffer_pair->first,
((last_buffer_pair->second != NULL) ? last_buffer_pair->second->GetId() : -1),
mFinishBufferQueue_.size());
}
}
// 2. Next 切换为 Drawing 状态
mDrawingWriteBackBuffer_ = mNextWriteBackBuffer_;
if(mWriteBackBQ_->QueueBuffer(mNextWriteBackBuffer_)){
HWC2_ALOGE("display=%d WBBuffer Queue fail, w=%d h=%d format=%d",
iWriteBackDisplayId_,
iWBWidth_,
iWBHeight_,
iWBFormat_);
return -1;
}
// 3. 申请 Next Buffer
std::shared_ptr<DrmBuffer> next
= mWriteBackBQ_->DequeueDrmBuffer(iWBWidth_,
iWBHeight_,
iWBFormat_,
RK_GRALLOC_USAGE_STRIDE_ALIGN_16 |
MALI_GRALLOC_USAGE_NO_AFBC,
"WriteBackBuffer");
if(!next->initCheck()){
HWC2_ALOGE("display=%d WBBuffer Dequeue fail, w=%d h=%d format=%d",
iWriteBackDisplayId_,
iWBWidth_,
iWBHeight_,
iWBFormat_);
return -1;
}
HWC2_ALOGD_IF_INFO("display=%d success, w=%d h=%d format=%d",
iWriteBackDisplayId_,
iWBWidth_,
iWBHeight_,
iWBFormat_);
mNextWriteBackBuffer_ = next;
return 0;
}
} // namespace android