/* * 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 #include #include #include #include #include #include #include #include //XML prase #include 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>(crtc->id(),std::make_shared())); 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 drm = std::make_unique(); 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.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 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 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 lock(mRecursiveMutex); return iWriteBackDisplayId_; } bool ResourceManager::isWBMode() const { std::unique_lock lock(mRecursiveMutex); return bEnableWriteBackRef_ > 0; } const DrmMode& ResourceManager::GetWBMode() const { std::unique_lock lock(mRecursiveMutex); return mWBMode_; } bool ResourceManager::IsDisableHwVirtualDisplay(){ std::unique_lock lock(mRecursiveMutex); return mVDMode_ == HWC2_DISABLE_HW_VIRTUAL_DISPLAY; } bool ResourceManager::IsWriteBackByVop(){ std::unique_lock lock(mRecursiveMutex); return mVDMode_ == HWC2_HW_VIRTUAL_DISPLAY_USE_VOP; } bool ResourceManager::IsWriteBackByRga(){ std::unique_lock lock(mRecursiveMutex); return mVDMode_ == HWC2_HW_VIRTUAL_DISPLAY_USE_RGA; } HwVirtualDisplayMode_t ResourceManager::ChooseWriteBackMode(int display){ std::unique_lock 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 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(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(); 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 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 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(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 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 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 ResourceManager::GetResetWBBuffer(){ std::unique_lock lock(mRecursiveMutex); if(mResetBackBuffer_ == NULL){ mResetBackBuffer_ = std::make_shared(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 ResourceManager::GetNextWBBuffer(){ std::unique_lock lock(mRecursiveMutex); return mNextWriteBackBuffer_; } std::shared_ptr ResourceManager::GetDrawingWBBuffer(){ std::unique_lock lock(mRecursiveMutex); return mDrawingWriteBackBuffer_;; } int ResourceManager::GetFinishWBBufferSize(){ std::unique_lock 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 lock(mRecursiveMutex); if(mFinishBufferQueue_.size() == 0){ HWC2_ALOGE("mFinishBufferQueue_ size is 0"); return -1; } std::shared_ptr output_buffer = NULL; uint64_t output_frame_no = 0; std::queue 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 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 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