mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-12-02 12:28:05 +00:00
update drawingengine sample code
Signed-off-by: mk_gc <mengkun@huawei.com> Change-Id: I8dba83adee3c57fb257634bbeaa1e80f6ae47dd3 Signed-off-by: mk_gc <mengkun@huawei.com>
This commit is contained in:
parent
516d897ab7
commit
981f1e5f5e
@ -55,6 +55,7 @@
|
||||
"//foundation/graphic/standard/rosen/modules/composer:libcomposer",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/rosen/samples/2d_graphics:drawing_sample_rs",
|
||||
"//foundation/graphic/standard/rosen/samples/2d_graphics:drawing_engine_sample",
|
||||
"//foundation/graphic/standard/rosen/samples/2d_graphics/test:drawing_sample",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/test:render_service_client",
|
||||
|
@ -15,59 +15,57 @@ import("//build/ohos.gni")
|
||||
import("//foundation/graphic/standard/graphic_config.gni")
|
||||
import("//third_party/wayland_standard/wayland_protocol.gni")
|
||||
|
||||
if (ace_enable_gpu) {
|
||||
ohos_executable("render_context_sample") {
|
||||
install_enable = true
|
||||
cflags = [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-unused-variable",
|
||||
]
|
||||
ohos_executable("drawing_engine_sample") {
|
||||
install_enable = true
|
||||
cflags = [
|
||||
"-Wall",
|
||||
"-Werror",
|
||||
"-Wno-unused-parameter",
|
||||
"-Wno-missing-field-initializers",
|
||||
"-Wno-unused-variable",
|
||||
]
|
||||
|
||||
sources = [
|
||||
"main.cpp",
|
||||
"render_context_sample.cpp",
|
||||
]
|
||||
sources = [
|
||||
"drawing_engine_sample.cpp",
|
||||
"main.cpp",
|
||||
]
|
||||
|
||||
configs = []
|
||||
configs = []
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics/include",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics/src",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/src",
|
||||
"//foundation/graphic/standard/rosen/modules/composer/hdi_backend/include",
|
||||
"//foundation/graphic/standard/interfaces/innerkits/vsync_module",
|
||||
"//foundation/graphic/standard/utils/sync_fence/export",
|
||||
"//foundation/graphic/standard/rosen/include/common",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/include",
|
||||
]
|
||||
include_dirs = [
|
||||
"include",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics/include",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics/src",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/src",
|
||||
"//foundation/graphic/standard/rosen/modules/composer/hdi_backend/include",
|
||||
"//foundation/graphic/standard/interfaces/innerkits/vsync_module",
|
||||
"//foundation/graphic/standard/utils/sync_fence/export",
|
||||
"//foundation/graphic/standard/rosen/include/common",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos",
|
||||
"//foundation/graphic/standard:libsurface",
|
||||
"//foundation/graphic/standard:libvsync_client",
|
||||
"//foundation/graphic/standard:libwmclient",
|
||||
"//foundation/graphic/standard:libwmservice",
|
||||
"//foundation/graphic/standard/frameworks/vsync:libvsync_module",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/rosen/modules/composer:libcomposer",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base",
|
||||
"//foundation/graphic/standard/utils:sync_fence",
|
||||
"//third_party/zlib:libz",
|
||||
]
|
||||
deps = [
|
||||
"//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos",
|
||||
"//foundation/graphic/standard:libsurface",
|
||||
"//foundation/graphic/standard:libvsync_client",
|
||||
"//foundation/graphic/standard:libwmclient",
|
||||
"//foundation/graphic/standard:libwmservice",
|
||||
"//foundation/graphic/standard/frameworks/vsync:libvsync_module",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/rosen/modules/composer:libcomposer",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base",
|
||||
"//foundation/graphic/standard/utils:sync_fence",
|
||||
"//third_party/zlib:libz",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"hilog_native:libhilog",
|
||||
"multimedia_image_standard:image_native",
|
||||
"utils_base:utils",
|
||||
]
|
||||
external_deps = [
|
||||
"hilog_native:libhilog",
|
||||
"multimedia_image_standard:image_native",
|
||||
"utils_base:utils",
|
||||
]
|
||||
|
||||
subsystem_name = "graphic"
|
||||
part_name = "graphic_standard"
|
||||
}
|
||||
subsystem_name = "graphic"
|
||||
part_name = "graphic_standard"
|
||||
}
|
||||
|
||||
ohos_executable("drawing_sample_rs") {
|
||||
|
385
rosen/samples/2d_graphics/drawing_engine_sample.cpp
Normal file
385
rosen/samples/2d_graphics/drawing_engine_sample.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "drawing_engine_sample.h"
|
||||
|
||||
#include "window.h"
|
||||
#include <securec.h>
|
||||
#include <vsync_generator.h>
|
||||
#include <vsync_controller.h>
|
||||
#include <vsync_distributor.h>
|
||||
#include <vsync_helper.h>
|
||||
#include <vsync_receiver.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::Rosen;
|
||||
|
||||
namespace {
|
||||
sptr<VSyncReceiver> g_receiver = nullptr;
|
||||
}
|
||||
|
||||
void DrawingEngineSample::Run()
|
||||
{
|
||||
auto generator = CreateVSyncGenerator();
|
||||
sptr<VSyncController> vsyncController = new VSyncController(generator, 0);
|
||||
sptr<VSyncDistributor> vsyncDistributor = new VSyncDistributor(vsyncController, "HelloComposer");
|
||||
sptr<VSyncConnection> vsyncConnection = new VSyncConnection(vsyncDistributor, "HelloComposer");
|
||||
vsyncDistributor->AddConnection(vsyncConnection);
|
||||
|
||||
std::cout << "start to HdiBackend::GetInstance" << std::endl;
|
||||
backend_ = OHOS::Rosen::HdiBackend::GetInstance();
|
||||
if (backend_ == nullptr) {
|
||||
std::cout << "HdiBackend::GetInstance fail" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
backend_->RegScreenHotplug(DrawingEngineSample::OnScreenPlug, this);
|
||||
while (1) {
|
||||
if (output_ != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!initDeviceFinished_) {
|
||||
if (deviceConnected_) {
|
||||
CreatePhysicalScreen();
|
||||
}
|
||||
initDeviceFinished_ = true;
|
||||
}
|
||||
std::cout << "Init screen succeed" << std::endl;
|
||||
|
||||
backend_->RegPrepareComplete(DrawingEngineSample::OnPrepareCompleted, this);
|
||||
|
||||
sleep(1);
|
||||
|
||||
auto runner = OHOS::AppExecFwk::EventRunner::Create(false);
|
||||
auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
|
||||
g_receiver = new VSyncReceiver(vsyncConnection, handler);
|
||||
g_receiver->Init();
|
||||
handler->PostTask(std::bind(&DrawingEngineSample::Init, this));
|
||||
runner->Run();
|
||||
}
|
||||
|
||||
void DrawingEngineSample::OnScreenPlug(std::shared_ptr<HdiOutput> &output, bool connected, void* data)
|
||||
{
|
||||
std::cout << "enter OnScreenPlug, connected is " << connected << std::endl;
|
||||
auto* thisPtr = static_cast<DrawingEngineSample *>(data);
|
||||
thisPtr->OnHotPlugEvent(output, connected);
|
||||
}
|
||||
|
||||
void DrawingEngineSample::OnPrepareCompleted(
|
||||
std::shared_ptr<RSSurface> &rsSurface, const struct PrepareCompleteParam ¶m, void* data)
|
||||
{
|
||||
if (!param.needFlushFramebuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rsSurface == nullptr) {
|
||||
LOGE("surface is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == nullptr) {
|
||||
LOGE("data ptr is null");
|
||||
return;
|
||||
}
|
||||
|
||||
auto* thisPtr = static_cast<DrawingEngineSample *>(data);
|
||||
sptr<Surface> surface = std::static_pointer_cast<RSSurfaceOhos>(rsSurface)->GetSurface();
|
||||
thisPtr->DoPrepareCompleted(surface, param);
|
||||
}
|
||||
|
||||
void DrawingEngineSample::InitContext()
|
||||
{
|
||||
drawingProxy = new DrawingProxy();
|
||||
drawingProxy->InitDrawContext();
|
||||
}
|
||||
|
||||
void DrawingEngineSample::Init()
|
||||
{
|
||||
LOGI("DrawingEngineSample::Init+");
|
||||
CreateDrawingSurface();
|
||||
InitContext();
|
||||
Sync(0, nullptr);
|
||||
Initilized = true;
|
||||
LOGI("DrawingEngineSample::Init-");
|
||||
}
|
||||
|
||||
void DrawingEngineSample::Sync(int64_t, void *data)
|
||||
{
|
||||
VSyncReceiver::FrameCallback fcb = {
|
||||
.userData_ = data,
|
||||
.callback_ = std::bind(&DrawingEngineSample::Sync, this, ::std::placeholders::_1, ::std::placeholders::_2),
|
||||
};
|
||||
|
||||
if (g_receiver != nullptr) {
|
||||
g_receiver->RequestNextVSync(fcb);
|
||||
}
|
||||
|
||||
if (!ready_) {
|
||||
LOGE("hdi screen is not ready");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Initilized == false) {
|
||||
LOGI("call init function");
|
||||
return;
|
||||
}
|
||||
|
||||
OutPutDisplay();
|
||||
}
|
||||
|
||||
void DrawingEngineSample::CreateDrawingSurface()
|
||||
{
|
||||
drawingCSurface = Surface::CreateSurfaceAsConsumer();
|
||||
drawingCSurface->SetDefaultWidthAndHeight(drawingWidth, drawingHeight);
|
||||
drawingCSurface->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA);
|
||||
|
||||
sptr<IBufferProducer> producer = drawingCSurface->GetProducer();
|
||||
drawingPSurface= Surface::CreateSurfaceAsProducer(producer);
|
||||
drawingCSurface->RegisterConsumerListener(this);
|
||||
|
||||
prevBufferMap_[drawingCSurface->GetUniqueId()] = nullptr;
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()] = SyncFence::INVALID_FENCE;
|
||||
}
|
||||
|
||||
void DrawingEngineSample::OnBufferAvailable()
|
||||
{
|
||||
}
|
||||
|
||||
void DrawingEngineSample::Draw(SkCanvas* canvas)
|
||||
{
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setColor(0xFF9A67BE);
|
||||
paint.setStrokeWidth(20);
|
||||
canvas->skew(1, 0);
|
||||
canvas->drawLine(32, 96,32, 160, paint); // point position
|
||||
canvas->skew(-2, 0);
|
||||
canvas->drawLine(288, 96, 288, 160, paint); // point position
|
||||
}
|
||||
|
||||
SurfaceError DrawingEngineSample::DoDraw()
|
||||
{
|
||||
LOGI("DrawingEngineSample::DoDraw+");
|
||||
|
||||
std::shared_ptr<RSSurface> rsSurface = OHOS::Rosen::RSSurfaceOhos::CreateSurface(drawingPSurface);
|
||||
rsSurface->SetDrawingProxy(drawingProxy);
|
||||
|
||||
auto surfaceFrame = rsSurface->RequestFrame(drawingWidth, drawingHeight);
|
||||
if (surfaceFrame == nullptr) {
|
||||
std::cout << "Request Frame Failed" << std::endl;
|
||||
return SURFACE_ERROR_ERROR;
|
||||
}
|
||||
|
||||
SkCanvas* canvas = rsSurface->GetCanvas(surfaceFrame);
|
||||
Draw(canvas);
|
||||
|
||||
rsSurface->FlushFrame(surfaceFrame);
|
||||
|
||||
LOGI("DrawingEngineSample::DoDraw-");
|
||||
return SURFACE_ERROR_OK;
|
||||
}
|
||||
|
||||
bool DrawingEngineSample::DrawDrawingLayer(std::shared_ptr<HdiLayerInfo> &layer)
|
||||
{
|
||||
int32_t zorder = 1;
|
||||
IRect dstRect;
|
||||
dstRect.x = 0; // Absolute coordinates, with offset
|
||||
dstRect.y = 0;
|
||||
dstRect.w = display_w;
|
||||
dstRect.h = display_h;
|
||||
int index = -1;
|
||||
|
||||
SurfaceError err = DoDraw();
|
||||
if (err != SURFACE_ERROR_OK) {
|
||||
std::cout << "DoDraw failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
OHOS::sptr<SurfaceBuffer> cbuffer = nullptr;
|
||||
int32_t fence = -1;
|
||||
int64_t timestamp;
|
||||
Rect damage;
|
||||
SurfaceError ret = drawingCSurface->AcquireBuffer(cbuffer, fence, timestamp, damage);
|
||||
sptr<SyncFence> acquireSyncFence = new SyncFence(fence);
|
||||
if (ret != SURFACE_ERROR_OK) {
|
||||
std::cout << "Acquire cBuffer failed: " << ret << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
IRect srcRect;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
srcRect.w = drawingWidth;
|
||||
srcRect.h = drawingHeight;
|
||||
LayerAlpha alpha = { .enPixelAlpha = true };
|
||||
layer->SetSurface(drawingCSurface);
|
||||
layer->SetBuffer(cbuffer, acquireSyncFence, prevBufferMap_[drawingCSurface->GetUniqueId()],
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()]);
|
||||
layer->SetZorder(zorder);
|
||||
layer->SetAlpha(alpha);
|
||||
layer->SetTransform(TransformType::ROTATE_NONE);
|
||||
if (index == 0) {
|
||||
// COMPOSITION_CLIENT
|
||||
layer->SetCompositionType(CompositionType::COMPOSITION_DEVICE);
|
||||
} else {
|
||||
layer->SetCompositionType(CompositionType::COMPOSITION_DEVICE);
|
||||
}
|
||||
layer->SetVisibleRegion(1, srcRect);
|
||||
layer->SetDirtyRegion(srcRect);
|
||||
layer->SetLayerSize(dstRect);
|
||||
layer->SetBlendType(BlendType::BLEND_SRC);
|
||||
layer->SetCropRect(srcRect);
|
||||
layer->SetPreMulti(false);
|
||||
|
||||
prevBufferMap_[drawingCSurface->GetUniqueId()] = cbuffer;
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()] = acquireSyncFence;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DrawingEngineSample::OutPutDisplay()
|
||||
{
|
||||
static int32_t count = 0;
|
||||
std::shared_ptr<HdiLayerInfo> drawingLayer = HdiLayerInfo::CreateHdiLayerInfo();
|
||||
do {
|
||||
std::cout << " draw count " << count << std::endl;
|
||||
LOGI("OutPutDisplay draw count is %{pubic}d", count);
|
||||
|
||||
if (!DrawDrawingLayer(drawingLayer)) {
|
||||
std::cout << "DrawDrawingLayer failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<LayerInfoPtr> layers;
|
||||
layers.push_back(drawingLayer);
|
||||
output_->SetLayerInfo(layers);
|
||||
|
||||
IRect damageRect;
|
||||
damageRect.x = 0;
|
||||
damageRect.y = 0;
|
||||
damageRect.w = display_w;
|
||||
damageRect.h = display_h;
|
||||
output_->SetOutputDamage(1, damageRect);
|
||||
|
||||
backend_->Repaint(outputs_);
|
||||
std::cout << "draw count " << count << std::endl;
|
||||
std::cout << "display width is " << display_w << ", display height is " << display_h << std::endl;
|
||||
|
||||
count++;
|
||||
} while (false);
|
||||
}
|
||||
|
||||
void DrawingEngineSample::CreatePhysicalScreen()
|
||||
{
|
||||
screen_ = HdiScreen::CreateHdiScreen(output_->GetScreenId());
|
||||
screen_->Init();
|
||||
screen_->GetScreenSupportedModes(displayModeInfos_);
|
||||
outputs_.push_back(output_);
|
||||
size_t supportModeNum = displayModeInfos_.size();
|
||||
if (supportModeNum > 0) {
|
||||
screen_->GetScreenMode(currentModeIndex_);
|
||||
for (size_t i = 0; i < supportModeNum; i++) {
|
||||
if (displayModeInfos_[i].id == static_cast<int32_t>(currentModeIndex_)) {
|
||||
this->freq_ = displayModeInfos_[i].freshRate;
|
||||
this->display_w = displayModeInfos_[i].width;
|
||||
this->display_h = displayModeInfos_[i].height;
|
||||
}
|
||||
}
|
||||
screen_->SetScreenPowerStatus(DispPowerStatus::POWER_STATUS_ON);
|
||||
screen_->SetScreenMode(currentModeIndex_);
|
||||
|
||||
DispPowerStatus powerState;
|
||||
screen_->SetScreenPowerStatus(DispPowerStatus::POWER_STATUS_ON);
|
||||
screen_->GetScreenPowerStatus(powerState);
|
||||
}
|
||||
|
||||
DisplayCapability info;
|
||||
screen_->GetScreenCapability(info);
|
||||
|
||||
std::cout << "display width is " << this->display_w << " display height is " << this->display_h << std::endl;
|
||||
|
||||
drawingWidth = this->display_w;
|
||||
drawingHeight = this->display_h;
|
||||
|
||||
ready_ = true;
|
||||
}
|
||||
|
||||
void DrawingEngineSample::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
|
||||
{
|
||||
/*
|
||||
* Currently, IPC communication cannot be nested. Therefore, Vblank registration can be
|
||||
* initiated only after the initialization of the device is complete.
|
||||
*/
|
||||
output_ = output;
|
||||
deviceConnected_ = connected;
|
||||
|
||||
if (!initDeviceFinished_) {
|
||||
std::cout << "Init the device has not finished yet" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Callback HotPlugEvent, connected is " << connected << std::endl;
|
||||
if (connected) {
|
||||
CreatePhysicalScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingEngineSample::DoPrepareCompleted(sptr<Surface> &surface, const struct PrepareCompleteParam ¶m)
|
||||
{
|
||||
BufferRequestConfig requestConfig = {
|
||||
.width = display_w, // need display width
|
||||
.height = display_h, // need display height
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_BGRA_8888,
|
||||
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA | HBM_USE_MEM_FB,
|
||||
.timeout = 0,
|
||||
};
|
||||
|
||||
int32_t releaseFence = -1;
|
||||
sptr<SurfaceBuffer> fbBuffer = nullptr;
|
||||
SurfaceError err = surface->RequestBuffer(fbBuffer, releaseFence, requestConfig);
|
||||
if (err != 0) {
|
||||
LOGE("RequestBuffer failed: %{public}s", SurfaceErrorStr(err).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
sptr<SyncFence> tempFence = new SyncFence(releaseFence);
|
||||
tempFence->Wait(100); // 100 ms
|
||||
|
||||
int32_t ret = 0;
|
||||
auto addr = static_cast<uint8_t *>(fbBuffer->GetVirAddr());
|
||||
ret = memset_s(addr, fbBuffer->GetSize(), 0, fbBuffer->GetSize());
|
||||
if (ret != 0) {
|
||||
std::cout << "memset_s failed" << std::endl;
|
||||
}
|
||||
|
||||
BufferFlushConfig flushConfig = {
|
||||
.damage = {
|
||||
.w = display_w,
|
||||
.h = display_h,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* if use GPU produce data, flush with gpu fence
|
||||
*/
|
||||
ret = surface->FlushBuffer(fbBuffer, -1, flushConfig);
|
||||
if (ret != 0) {
|
||||
std::cout << "DoPrepareCompleted FlushBuffer failed"<< std::endl;
|
||||
}
|
||||
}
|
56
rosen/samples/2d_graphics/render_context_sample.h → rosen/samples/2d_graphics/drawing_engine_sample.h
Executable file → Normal file
56
rosen/samples/2d_graphics/render_context_sample.h → rosen/samples/2d_graphics/drawing_engine_sample.h
Executable file → Normal file
@ -13,81 +13,71 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef RENDER_CONTEXT_SAMPLE_H
|
||||
#define RENDER_CONTEXT_SAMPLE_H
|
||||
#ifndef DRAWING_ENGINE_SAMPLE_H
|
||||
#define DRAWING_ENGINE_SAMPLE_H
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkPaint.h"
|
||||
|
||||
#include <display_type.h>
|
||||
#include <surface.h>
|
||||
#include <sync_fence.h>
|
||||
|
||||
#include <event_handler.h>
|
||||
#include "hdi_backend.h"
|
||||
#include "hdi_layer_info.h"
|
||||
#include "hdi_output.h"
|
||||
#include "hdi_screen.h"
|
||||
#include "render_context/render_context.h"
|
||||
#include <unordered_map>
|
||||
#include "drawing_engine/drawing_utils.h"
|
||||
#include "drawing_engine/drawing_proxy.h"
|
||||
#include "drawing_engine/drawing_surface/rs_surface_ohos.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
|
||||
class RenderContextSample : public IBufferConsumerListenerClazz {
|
||||
class DrawingEngineSample : public IBufferConsumerListenerClazz {
|
||||
public:
|
||||
RenderContextSample() = default;
|
||||
virtual ~RenderContextSample() = default;
|
||||
|
||||
DrawingEngineSample() = default;
|
||||
virtual ~DrawingEngineSample() = default;
|
||||
void Run();
|
||||
|
||||
private:
|
||||
uint32_t freq_ = 30;
|
||||
uint32_t display_w = 480;
|
||||
uint32_t display_h = 960;
|
||||
uint32_t display_w = 0;
|
||||
uint32_t display_h = 0;
|
||||
uint32_t currentModeIndex_ = 0;
|
||||
uint32_t backGroundWidth = 0;
|
||||
uint32_t backGroundHeight = 0;
|
||||
uint32_t drawingWidth = 0;
|
||||
uint32_t drawingHeight = 0;
|
||||
std::vector<DisplayModeInfo> displayModeInfos_;
|
||||
std::vector<std::shared_ptr<HdiOutput>> outputs_;
|
||||
|
||||
sptr<Surface> backGroundCSurface;
|
||||
sptr<Surface> backGroundPSurface;
|
||||
std::shared_ptr<OHOS::AppExecFwk::EventHandler> handler;
|
||||
sptr<Surface> drawingCSurface;
|
||||
sptr<Surface> drawingPSurface;
|
||||
|
||||
bool ready_ = false;
|
||||
bool initDeviceFinished_ = false;
|
||||
bool deviceConnected_ = false;
|
||||
bool Initilized = false;
|
||||
std::unique_ptr<HdiScreen> screen_ = nullptr;
|
||||
HdiBackend* backend_ = nullptr;
|
||||
std::shared_ptr<HdiOutput> output_ = nullptr;
|
||||
struct NativeWindow* nwindow = nullptr;
|
||||
|
||||
RenderContext* renderContext = nullptr;
|
||||
EGLSurface eglSurface = EGL_NO_SURFACE;
|
||||
DrawingProxy* drawingProxy = nullptr;
|
||||
|
||||
std::unordered_map<uint64_t, sptr<SurfaceBuffer>> prevBufferMap_;
|
||||
std::unordered_map<uint64_t, sptr<SyncFence>> prevFenceMap_;
|
||||
|
||||
void Init();
|
||||
void InitEGL();
|
||||
void Draw();
|
||||
void DrawSurface();
|
||||
void InitContext();
|
||||
void OutPutDisplay();
|
||||
void Sync(int64_t, void *data);
|
||||
void CreatePhysicalScreen();
|
||||
void DoPrepareCompleted(sptr<Surface> &surface, const struct PrepareCompleteParam ¶m);
|
||||
virtual void OnBufferAvailable() override;
|
||||
SurfaceError ProduceBackGroundBuffer(uint32_t width, uint32_t height);
|
||||
SurfaceError ProduceDrawingBuffer(uint32_t width, uint32_t height);
|
||||
bool FillDrawingLayer(std::shared_ptr<HdiLayerInfo> &showLayer, uint32_t index, uint32_t zorder, IRect &dstRect);
|
||||
bool FillBackGroundLayer(std::shared_ptr<HdiLayerInfo> &showLayer, uint32_t zorder, IRect &dstRect);
|
||||
bool DrawBackgroundLayer(std::shared_ptr<HdiLayerInfo> &layer);
|
||||
SurfaceError DoDraw();
|
||||
void Draw(SkCanvas* canvas);
|
||||
bool DrawDrawingLayer(std::shared_ptr<HdiLayerInfo> &layer);
|
||||
void CreateBackGroundSurface();
|
||||
void CreateDrawingSurface();
|
||||
void OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected);
|
||||
|
||||
static void OnScreenPlug(std::shared_ptr<HdiOutput> &output, bool connected, void* data);
|
||||
static void OnPrepareCompleted(OHOS::sptr<Surface> &surface, const struct PrepareCompleteParam ¶m, void* data);
|
||||
static void OnPrepareCompleted(
|
||||
std::shared_ptr<RSSurface> &rsSurface, const struct PrepareCompleteParam ¶m, void* data);
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -13,11 +13,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "render_context_sample.h"
|
||||
#include "drawing_engine_sample.h"
|
||||
|
||||
int32_t main(int32_t argc, const char *argv[])
|
||||
{
|
||||
OHOS::Rosen::RenderContextSample m;
|
||||
OHOS::Rosen::DrawingEngineSample m;
|
||||
m.Run();
|
||||
|
||||
return 0;
|
||||
|
@ -1,508 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "render_context_sample.h"
|
||||
|
||||
#include "window.h"
|
||||
#include <securec.h>
|
||||
#include <vsync_helper.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::Rosen;
|
||||
|
||||
void RenderContextSample::Run()
|
||||
{
|
||||
std::cout << "start to HdiBackend::GetInstance" << std::endl;
|
||||
backend_ = OHOS::Rosen::HdiBackend::GetInstance();
|
||||
if (backend_ == nullptr) {
|
||||
std::cout << "HdiBackend::GetInstance fail" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
backend_->RegScreenHotplug(RenderContextSample::OnScreenPlug, this);
|
||||
while (1) {
|
||||
if (output_ != nullptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!initDeviceFinished_) {
|
||||
if (deviceConnected_) {
|
||||
CreatePhysicalScreen();
|
||||
}
|
||||
initDeviceFinished_ = true;
|
||||
}
|
||||
std::cout << "Init screen succeed" << std::endl;
|
||||
|
||||
backend_->RegPrepareComplete(RenderContextSample::OnPrepareCompleted, this);
|
||||
|
||||
sleep(1);
|
||||
|
||||
auto runner = OHOS::AppExecFwk::EventRunner::Create(false);
|
||||
auto handler = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
|
||||
handler->PostTask(std::bind(&RenderContextSample::Init, this));
|
||||
runner->Run();
|
||||
}
|
||||
|
||||
void RenderContextSample::OnScreenPlug(std::shared_ptr<HdiOutput> &output, bool connected, void* data)
|
||||
{
|
||||
std::cout << "enter OnScreenPlug, connected is " << connected << std::endl;
|
||||
auto* thisPtr = static_cast<RenderContextSample *>(data);
|
||||
thisPtr->OnHotPlugEvent(output, connected);
|
||||
}
|
||||
|
||||
void RenderContextSample::OnPrepareCompleted(sptr<Surface> &surface, const struct PrepareCompleteParam ¶m, void* data)
|
||||
{
|
||||
if (!param.needFlushFramebuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "OnPrepareCompleted param.layer size is " << (int)param.layers.size() << std::endl;
|
||||
auto* thisPtr = static_cast<RenderContextSample *>(data);
|
||||
thisPtr->DoPrepareCompleted(surface, param);
|
||||
}
|
||||
|
||||
void RenderContextSample::InitEGL()
|
||||
{
|
||||
renderContext = new RenderContext();
|
||||
renderContext->InitializeEglContext();
|
||||
}
|
||||
|
||||
void RenderContextSample::Init()
|
||||
{
|
||||
backGroundWidth = 2560;
|
||||
backGroundHeight = 1600;
|
||||
|
||||
drawingWidth = 1200;
|
||||
drawingHeight = 800;
|
||||
|
||||
CreateBackGroundSurface();
|
||||
|
||||
CreateDrawingSurface();
|
||||
|
||||
InitEGL();
|
||||
|
||||
Sync(0, nullptr);
|
||||
}
|
||||
|
||||
void RenderContextSample::Sync(int64_t, void *data)
|
||||
{
|
||||
struct OHOS::FrameCallback cb = {
|
||||
.frequency_ = freq_,
|
||||
.timestamp_ = 0,
|
||||
.userdata_ = data,
|
||||
.callback_ = std::bind(&RenderContextSample::Sync, this, SYNC_FUNC_ARG),
|
||||
};
|
||||
|
||||
OHOS::VsyncError ret = OHOS::VsyncHelper::Current()->RequestFrameCallback(cb);
|
||||
if (ret) {
|
||||
std::cout << "RequestFrameCallback inner " << ret << std::endl;
|
||||
}
|
||||
|
||||
if (!ready_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Draw();
|
||||
}
|
||||
|
||||
void RenderContextSample::CreateBackGroundSurface()
|
||||
{
|
||||
backGroundCSurface = Surface::CreateSurfaceAsConsumer();
|
||||
backGroundCSurface->SetDefaultWidthAndHeight(backGroundWidth, backGroundHeight);
|
||||
backGroundCSurface->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA);
|
||||
|
||||
sptr<IBufferProducer> producer = backGroundCSurface->GetProducer();
|
||||
backGroundPSurface= Surface::CreateSurfaceAsProducer(producer);
|
||||
backGroundCSurface->RegisterConsumerListener(this);
|
||||
|
||||
prevBufferMap_[backGroundCSurface->GetUniqueId()] = nullptr;
|
||||
prevFenceMap_[backGroundCSurface->GetUniqueId()] = SyncFence::INVALID_FENCE;
|
||||
}
|
||||
|
||||
void RenderContextSample::CreateDrawingSurface()
|
||||
{
|
||||
drawingCSurface = Surface::CreateSurfaceAsConsumer();
|
||||
drawingCSurface->SetDefaultWidthAndHeight(backGroundWidth, backGroundHeight);
|
||||
drawingCSurface->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA);
|
||||
|
||||
sptr<IBufferProducer> producer = drawingCSurface->GetProducer();
|
||||
drawingPSurface= Surface::CreateSurfaceAsProducer(producer);
|
||||
drawingCSurface->RegisterConsumerListener(this);
|
||||
|
||||
prevBufferMap_[drawingCSurface->GetUniqueId()] = nullptr;
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()] = SyncFence::INVALID_FENCE;
|
||||
}
|
||||
|
||||
void RenderContextSample::OnBufferAvailable()
|
||||
{
|
||||
}
|
||||
|
||||
SurfaceError RenderContextSample::ProduceBackGroundBuffer(uint32_t width, uint32_t height)
|
||||
{
|
||||
OHOS::sptr<SurfaceBuffer> buffer;
|
||||
int32_t releaseFence = -1;
|
||||
BufferRequestConfig config = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_RGBA_8888,
|
||||
.usage = backGroundPSurface->GetDefaultUsage(),
|
||||
};
|
||||
|
||||
SurfaceError ret = backGroundPSurface->RequestBuffer(buffer, releaseFence, config);
|
||||
if (ret != 0) {
|
||||
std::cout << "RequestBuffer failed:" << SurfaceErrorStr(ret).c_str() << std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
sptr<SyncFence> tempFence = new SyncFence(releaseFence);
|
||||
tempFence->Wait(100);
|
||||
|
||||
if (buffer == nullptr) {
|
||||
std::cout << "buffer is nullptr" << std::endl;
|
||||
return SURFACE_ERROR_NULLPTR;
|
||||
}
|
||||
|
||||
void* addr = static_cast<uint8_t *>(buffer->GetVirAddr());
|
||||
static uint32_t value = 0xffffffff;
|
||||
|
||||
uint32_t *pixel = static_cast<uint32_t*>(addr);
|
||||
|
||||
for (uint32_t x = 0; x < width; x++) {
|
||||
for (uint32_t y = 0; y < height; y++) {
|
||||
*pixel++ = value;
|
||||
}
|
||||
}
|
||||
|
||||
BufferFlushConfig flushConfig = {
|
||||
.damage = {
|
||||
.w = width,
|
||||
.h = height,
|
||||
},
|
||||
};
|
||||
|
||||
int32_t acquireFence = -1;
|
||||
ret = backGroundPSurface->FlushBuffer(buffer, acquireFence, flushConfig);
|
||||
|
||||
std::cout << "Sync: " << SurfaceErrorStr(ret).c_str() << std::endl;
|
||||
return SURFACE_ERROR_OK;
|
||||
}
|
||||
|
||||
SurfaceError RenderContextSample::ProduceDrawingBuffer(uint32_t width, uint32_t height)
|
||||
{
|
||||
std::cout << "ProduceDrawingBuffer start" << std::endl;
|
||||
|
||||
if (nwindow == nullptr) {
|
||||
nwindow = CreateNativeWindowFromSurface(&drawingPSurface);
|
||||
eglSurface = renderContext->CreateEGLSurface((EGLNativeWindowType)nwindow);
|
||||
}
|
||||
|
||||
NativeWindowHandleOpt(nwindow, SET_BUFFER_GEOMETRY, width, height);
|
||||
|
||||
renderContext->MakeCurrent(eglSurface);
|
||||
|
||||
SkCanvas* canvas = renderContext->AcquireCanvas(width, height);
|
||||
|
||||
canvas->clear(SkColorSetARGB(0x20, 0x20, 0x20, 0xFF));
|
||||
SkPaint paint;
|
||||
paint.setColor(SK_ColorRED);
|
||||
paint.setAntiAlias(true);
|
||||
canvas->drawCircle(128, 128, 90, paint);
|
||||
paint.setColor(SK_ColorGREEN);
|
||||
canvas->drawCircle(86, 86, 20, paint);
|
||||
canvas->drawCircle(160, 76, 20, paint);
|
||||
canvas->drawCircle(140, 150, 35, paint);
|
||||
|
||||
renderContext->RenderFrame();
|
||||
renderContext->SwapBuffers(eglSurface);
|
||||
|
||||
std::cout << "ProduceDrawingBuffer end" << std::endl;
|
||||
|
||||
return SURFACE_ERROR_OK;
|
||||
}
|
||||
|
||||
bool RenderContextSample::DrawBackgroundLayer(std::shared_ptr<HdiLayerInfo> &layer)
|
||||
{
|
||||
int32_t zorder = 0;
|
||||
IRect dstRect;
|
||||
|
||||
dstRect.x = 0; // Absolute coordinates, with offset
|
||||
dstRect.y = 0;
|
||||
dstRect.w = 2560;
|
||||
dstRect.h = 1600;
|
||||
|
||||
if (!FillBackGroundLayer(layer, zorder, dstRect)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderContextSample::DrawDrawingLayer(std::shared_ptr<HdiLayerInfo> &layer)
|
||||
{
|
||||
int32_t zorder = 1;
|
||||
IRect dstRect;
|
||||
|
||||
dstRect.x = 0; // Absolute coordinates, with offset
|
||||
dstRect.y = 0;
|
||||
|
||||
dstRect.w = 1200;
|
||||
dstRect.h = 800;
|
||||
|
||||
if (!FillDrawingLayer(layer, 0, zorder, dstRect)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderContextSample::Draw()
|
||||
{
|
||||
static int32_t count = 0;
|
||||
std::shared_ptr<HdiLayerInfo> backgroundLayer = HdiLayerInfo::CreateHdiLayerInfo();
|
||||
std::shared_ptr<HdiLayerInfo> drawingLayer = HdiLayerInfo::CreateHdiLayerInfo();
|
||||
do {
|
||||
std::cout << "+++++++ draw count " << count << std::endl;
|
||||
if (!DrawBackgroundLayer(backgroundLayer)) {
|
||||
std::cout << "DrawBackgroundLayer failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!DrawDrawingLayer(drawingLayer)) {
|
||||
std::cout << "DrawDrawingLayer failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<LayerInfoPtr> layers;
|
||||
layers.push_back(backgroundLayer);
|
||||
layers.push_back(drawingLayer);
|
||||
|
||||
output_->SetLayerInfo(layers);
|
||||
|
||||
IRect damageRect;
|
||||
damageRect.x = 0;
|
||||
damageRect.y = 0;
|
||||
damageRect.w = display_w;
|
||||
damageRect.h = display_h;
|
||||
output_->SetOutputDamage(1, damageRect);
|
||||
|
||||
backend_->Repaint(outputs_);
|
||||
std::cout << "------ draw count " << count << std::endl;
|
||||
count++;
|
||||
} while (false);
|
||||
}
|
||||
|
||||
bool RenderContextSample::FillDrawingLayer(std::shared_ptr<HdiLayerInfo> &showLayer, uint32_t index,
|
||||
uint32_t zorder, IRect &dstRect)
|
||||
{
|
||||
if (ProduceDrawingBuffer(drawingWidth, drawingHeight) != SURFACE_ERROR_OK) {
|
||||
std::cout << "FillDrawingLayer produce cBuffer failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
OHOS::sptr<SurfaceBuffer> cbuffer = nullptr;
|
||||
int32_t fence = -1;
|
||||
int64_t timestamp;
|
||||
Rect damage;
|
||||
SurfaceError ret = drawingCSurface->AcquireBuffer(cbuffer, fence, timestamp, damage);
|
||||
sptr<SyncFence> acquireSyncFence = new SyncFence(fence);
|
||||
if (ret != SURFACE_ERROR_OK) {
|
||||
std::cout << "Acquire cBuffer failed: " << ret << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
IRect srcRect;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
srcRect.w = drawingWidth;
|
||||
srcRect.h = drawingHeight;
|
||||
|
||||
LayerAlpha alpha = { .enPixelAlpha = true };
|
||||
|
||||
showLayer->SetSurface(drawingCSurface);
|
||||
showLayer->SetBuffer(cbuffer, acquireSyncFence, prevBufferMap_[drawingCSurface->GetUniqueId()],
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()]);
|
||||
showLayer->SetZorder(zorder);
|
||||
showLayer->SetAlpha(alpha);
|
||||
showLayer->SetTransform(TransformType::ROTATE_NONE);
|
||||
if (index == 0) {
|
||||
// COMPOSITION_CLIENT
|
||||
showLayer->SetCompositionType(CompositionType::COMPOSITION_DEVICE);
|
||||
} else {
|
||||
showLayer->SetCompositionType(CompositionType::COMPOSITION_DEVICE);
|
||||
}
|
||||
showLayer->SetVisibleRegion(1, srcRect);
|
||||
showLayer->SetDirtyRegion(srcRect);
|
||||
showLayer->SetLayerSize(dstRect);
|
||||
showLayer->SetBlendType(BlendType::BLEND_SRC);
|
||||
showLayer->SetCropRect(srcRect);
|
||||
showLayer->SetPreMulti(false);
|
||||
|
||||
prevBufferMap_[drawingCSurface->GetUniqueId()] = cbuffer;
|
||||
prevFenceMap_[drawingCSurface->GetUniqueId()] = acquireSyncFence;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderContextSample::FillBackGroundLayer(std::shared_ptr<HdiLayerInfo> &showLayer, uint32_t zorder, IRect &dstRect)
|
||||
{
|
||||
if (ProduceBackGroundBuffer(dstRect.w, dstRect.h) != SURFACE_ERROR_OK) {
|
||||
std::cout << "Produce background cBuffer failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
OHOS::sptr<SurfaceBuffer> cbuffer = nullptr;
|
||||
int32_t fence = -1;
|
||||
int64_t timestamp;
|
||||
Rect damage;
|
||||
SurfaceError ret = backGroundCSurface->AcquireBuffer(cbuffer, fence, timestamp, damage);
|
||||
sptr<SyncFence> acquireSyncFence = new SyncFence(fence);
|
||||
if (ret != SURFACE_ERROR_OK) {
|
||||
std::cout << "Acquire cBuffer failed" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
IRect srcRect;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
srcRect.w = dstRect.w;
|
||||
srcRect.h = dstRect.h;
|
||||
|
||||
LayerAlpha alpha = { .enPixelAlpha = true };
|
||||
|
||||
showLayer->SetSurface(backGroundCSurface);
|
||||
showLayer->SetBuffer(cbuffer, acquireSyncFence, prevBufferMap_[backGroundCSurface->GetUniqueId()],
|
||||
prevFenceMap_[backGroundCSurface->GetUniqueId()]);
|
||||
showLayer->SetZorder(zorder);
|
||||
showLayer->SetAlpha(alpha);
|
||||
showLayer->SetCompositionType(CompositionType::COMPOSITION_DEVICE);
|
||||
showLayer->SetVisibleRegion(1, srcRect);
|
||||
showLayer->SetDirtyRegion(srcRect);
|
||||
showLayer->SetLayerSize(dstRect);
|
||||
showLayer->SetBlendType(BlendType::BLEND_SRC);
|
||||
showLayer->SetCropRect(srcRect);
|
||||
showLayer->SetPreMulti(false);
|
||||
|
||||
prevBufferMap_[backGroundCSurface->GetUniqueId()] = cbuffer;
|
||||
prevFenceMap_[backGroundCSurface->GetUniqueId()] = acquireSyncFence;
|
||||
|
||||
std::cout << "FillBackGroundLayer finished" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderContextSample::CreatePhysicalScreen()
|
||||
{
|
||||
screen_ = HdiScreen::CreateHdiScreen(output_->GetScreenId());
|
||||
screen_->Init();
|
||||
screen_->GetScreenSupportedModes(displayModeInfos_);
|
||||
outputs_.push_back(output_);
|
||||
size_t supportModeNum = displayModeInfos_.size();
|
||||
if (supportModeNum > 0) {
|
||||
screen_->GetScreenMode(currentModeIndex_);
|
||||
for (size_t i = 0; i < supportModeNum; i++) {
|
||||
if (displayModeInfos_[i].id == static_cast<int32_t>(currentModeIndex_)) {
|
||||
this->freq_ = displayModeInfos_[i].freshRate;
|
||||
this->display_w = displayModeInfos_[i].width;
|
||||
this->display_h = displayModeInfos_[i].height;
|
||||
}
|
||||
}
|
||||
screen_->SetScreenPowerStatus(DispPowerStatus::POWER_STATUS_ON);
|
||||
screen_->SetScreenMode(currentModeIndex_);
|
||||
|
||||
DispPowerStatus powerState;
|
||||
screen_->SetScreenPowerStatus(DispPowerStatus::POWER_STATUS_ON);
|
||||
screen_->GetScreenPowerStatus(powerState);
|
||||
}
|
||||
|
||||
DisplayCapability info;
|
||||
screen_->GetScreenCapability(info);
|
||||
|
||||
ready_ = true;
|
||||
}
|
||||
|
||||
void RenderContextSample::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
|
||||
{
|
||||
/*
|
||||
* Currently, IPC communication cannot be nested. Therefore, Vblank registration can be
|
||||
* initiated only after the initialization of the device is complete.
|
||||
*/
|
||||
output_ = output;
|
||||
deviceConnected_ = connected;
|
||||
|
||||
if (!initDeviceFinished_) {
|
||||
std::cout << "Init the device has not finished yet" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "Callback HotPlugEvent, connected is " << connected << std::endl;
|
||||
|
||||
if (connected) {
|
||||
CreatePhysicalScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContextSample::DoPrepareCompleted(sptr<Surface> &surface, const struct PrepareCompleteParam ¶m)
|
||||
{
|
||||
BufferRequestConfig requestConfig = {
|
||||
.width = display_w, // need display width
|
||||
.height = display_h, // need display height
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_BGRA_8888,
|
||||
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA | HBM_USE_MEM_FB,
|
||||
.timeout = 0,
|
||||
};
|
||||
|
||||
if (surface == nullptr) {
|
||||
std::cout << "surface is null" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t releaseFence = -1;
|
||||
sptr<SurfaceBuffer> fbBuffer = nullptr;
|
||||
SurfaceError ret1 = surface->RequestBuffer(fbBuffer, releaseFence, requestConfig);
|
||||
if (ret1 != 0) {
|
||||
std::cout << "RequestBuffer failed " << SurfaceErrorStr(ret1).c_str() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
sptr<SyncFence> tempFence = new SyncFence(releaseFence);
|
||||
tempFence->Wait(100);
|
||||
|
||||
|
||||
auto addr = static_cast<uint8_t *>(fbBuffer->GetVirAddr());
|
||||
int32_t ret2 = memset_s(addr, fbBuffer->GetSize(), 0, fbBuffer->GetSize());
|
||||
if (ret2 != 0) {
|
||||
std::cout << "memset_s failed" << std::endl;
|
||||
}
|
||||
|
||||
BufferFlushConfig flushConfig = {
|
||||
.damage = {
|
||||
.w = display_w,
|
||||
.h = display_h,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* if use GPU produce data, flush with gpu fence
|
||||
*/
|
||||
ret2 = surface->FlushBuffer(fbBuffer, -1, flushConfig);
|
||||
if (ret2 != 0) {
|
||||
std::cout << "DoPrepareCompleted FlushBuffer failed"<< std::endl;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user