如何自定义增加一个surfacetype

增加 surfacetype,方便在 device层做特殊的 plane处理

  1. 让应用传递一个特殊的 usage 参数,在 bufferqueue 这边 creatbuffer的时候去识别这个 usage

应用在创建buffer的时候通过setsuage将 框架层设置好的值初始化

    GSError BufferQueue::DoFlushBufferLocked(uint32_t sequence, sptr<BufferExtraData> bedata,
    sptr<SyncFence> fence, const BufferFlushConfigWithDamages &config)
{
    if (bufferQueueCache_.find(sequence) == bufferQueueCache_.end()) {
        BLOGE("bufferQueueCache not find sequence:%{public}u, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
        return SURFACE_ERROR_BUFFER_NOT_INCACHE;
    }
    if (bufferQueueCache_[sequence].isDeleting) {
        DeleteBufferInCache(sequence);
        BLOGD("DoFlushBuffer delete seq: %{public}d, uniqueId: %{public}" PRIu64 ".", sequence, uniqueId_);
        CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size()));
        return GSERROR_OK;
    }

    bufferQueueCache_[sequence].buffer->SetExtraData(bedata);
    bufferQueueCache_[sequence].buffer->SetSurfaceBufferTransform(transform_);

    uint64_t usage = static_cast<uint32_t>(bufferQueueCache_[sequence].config.usage);
    if (usage & BUFFER_USAGE_CPU_WRITE) {
        // api flush
        auto sret = bufferQueueCache_[sequence].buffer->FlushCache();
        if (sret != GSERROR_OK) {
            BLOGE("FlushCache ret: %{public}d, seq: %{public}u, uniqueId: %{public}" PRIu64 ".",
                sret, sequence, uniqueId_);
            return sret;
        }
    }
    // if failed, avoid to state rollback
    bufferQueueCache_[sequence].state = BUFFER_STATE_FLUSHED;
    bufferQueueCache_[sequence].fence = fence;
    bufferQueueCache_[sequence].damages = config.damages;
    dirtyList_.push_back(sequence);
    lastFlusedSequence_ = sequence;
    lastFlusedFence_ = fence;
    lastFlushedTransform_ = transform_;

    SetDesiredPresentTimestampAndUiTimestamp(sequence, config.desiredPresentTimestamp, config.timestamp);
    if (bufferQueueCache_[sequence].buffer->GetUsage() & GRALLOC_USAGE_PRI_XCOMPONENT_WHITEBOARD) {
        SetWhiteBoardStatus(true); //设置标识,标记应用传递的特殊usage
    }
    else {
        SetWhiteBoardStatus(false);
    }

    bool traceTag = IsTagEnabled(HITRACE_TAG_GRAPHIC_AGP);
    if (isLocalRender_) {
        AcquireFenceTracker::TrackFence(fence, traceTag);
    }
    // if you need dump SurfaceBuffer to file, you should execute hdc shell param set persist.dumpbuffer.enabled 1
    // and reboot your device
    static bool dumpBufferEnabled = system::GetParameter("persist.dumpbuffer.enabled", "0") != "0";
    if (dumpBufferEnabled) {
        // Wait for the status of the fence to change to SIGNALED.
        fence->Wait(-1);
        DumpToFileAsync(GetRealPid(), name_, bufferQueueCache_[sequence].buffer);
    }

    CountTrace(HITRACE_TAG_GRAPHIC_AGP, name_, static_cast<int32_t>(dirtyList_.size()));
    return GSERROR_OK;
}

SetWhiteBoardStatus(true); //设置标识,标记应用传递的特殊usage

  1. 在 foundation/graphic/graphic_2d/rosen/modules/render_service/core/pipeline/rs_composer_adapter.cpp 中 craetbuffer的时候特殊处理 layer
    return CreateTunnelLayer(node, false, true)
LayerInfoPtr RSComposerAdapter::CreateLayer(RSSurfaceRenderNode& node) const
{
    auto consumer = node.GetRSSurfaceHandler()->GetConsumer();
    if (consumer == nullptr) {
        RS_LOGE("RSComposerAdapter::CreateLayer get consumer fail");
        return nullptr;
    }
    if (consumer->GetWhiteBoardStatus()) {
        return CreateTunnelLayer(node, false, true);
    }
    sptr<SurfaceTunnelHandle> handle = consumer->GetTunnelHandle();
    if (handle != nullptr) {
        return CreateTunnelLayer(node);
    } else {
        return CreateBufferLayer(node);
    }
}

在 CreateTunnelLayer中,增加特殊layer的标识

  1. 在 foundation/graphic/graphic_2d/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp 中createlayer,加上自定义的surfacetype
    ```cpp

int32_t HdiLayer::CreateLayer(const LayerInfoPtr &layerInfo)
{
int32_t retCode = InitDevice();
if (retCode != GRAPHIC_DISPLAY_SUCCESS) {
return GRAPHIC_DISPLAY_NULL_PTR;
}

sptr<IConsumerSurface> surface = layerInfo->GetSurface();
if (surface == nullptr) {
    if (layerInfo->GetCompositionType() ==
        GraphicCompositionType::GRAPHIC_COMPOSITION_SOLID_COLOR) {
        bufferCacheCountMax_ = 0;
    } else {
        HLOGE("Create layer failed because the consumer surface is nullptr.");
        return GRAPHIC_DISPLAY_NULL_PTR;
    }
} else {
    // The number of buffers cycle in the surface is larger than the queue size.
    surface->GetCycleBuffersNumber(bufferCacheCountMax_);
}
uint32_t layerId = INT_MAX;
GraphicLayerInfo hdiLayerInfo = {
    .width = layerInfo->GetLayerSize().w,
    .height = layerInfo->GetLayerSize().h,
    .type = GRAPHIC_LAYER_TYPE_GRAPHIC,
    .pixFormat = GRAPHIC_PIXEL_FMT_RGBA_8888,
};
if (layerInfo->GetWhiteBoardStatus()) {
        hdiLayerInfo.type = GraphicLayerType::GRAPHIC_LAYER_TYPE_WHITEBOARD;
        //layerInfo->SetCompositionType(GRAPHIC_COMPOSITION_DEVICE_CLEAR);
        HLOGE("CXW Create hwc layer succeed  GetCompositionType %{public}d ",layerInfo->GetCompositionType());
}
int32_t ret = device_->CreateLayer(screenId_, hdiLayerInfo, bufferCacheCountMax_, layerId);
if (ret != GRAPHIC_DISPLAY_SUCCESS) {
    HLOGE("Create hwc layer failed, ret is %{public}d", ret);
    return ret;
}
ClearBufferCache();
bufferCache_.reserve(bufferCacheCountMax_);
layerId_ = layerId;

HLOGD("Create hwc layer succeed, layerId is %{public}u", layerId_);

CheckRet(device_->GetSupportedPresentTimestampType(screenId_, layerId_, supportedPresentTimestamptype_),
         "GetSupportedPresentTimestamp");
return ret;

}

```
通过上面的步骤就可以完成surfacetype的增加了,后面对这个layer进行处理的时候可以通过surfacetype的识别来进行特殊处理

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐