From 1e5d1f2fe5ef7f4749ebfe9e9c795acd6f4c52e2 Mon Sep 17 00:00:00 2001 From: stonesxd Date: Mon, 3 Jan 2022 14:49:07 +0800 Subject: [PATCH] add nativewindow to surface and init hello_composer demo Signed-off-by: stonesxd --- frameworks/surface/BUILD.gn | 2 + frameworks/surface/include/buffer_queue.h | 6 +- .../surface/include/buffer_queue_consumer.h | 1 + .../surface/include/buffer_queue_producer.h | 1 + frameworks/surface/include/consumer_surface.h | 3 + frameworks/surface/include/native_window.h | 55 +++ frameworks/surface/include/producer_surface.h | 3 + frameworks/surface/src/buffer_queue.cpp | 38 +- .../surface/src/buffer_queue_consumer.cpp | 8 + frameworks/surface/src/consumer_surface.cpp | 5 + frameworks/surface/src/native_window.cpp | 293 ++++++++++++++ frameworks/surface/src/surface_utils.cpp | 72 ++++ .../innerkits/surface/ibuffer_producer.h | 4 +- interfaces/innerkits/surface/surface.h | 3 + interfaces/innerkits/surface/surface_utils.h | 44 +++ interfaces/innerkits/surface/window.h | 92 +++++ ohos.build | 2 + rosen/modules/composer/BUILD.gn | 2 +- .../composer/hdi_backend/src/hdi_backend.cpp | 25 +- .../composer/hdi_backend/src/hdi_layer.cpp | 1 - rosen/samples/composer/BUILD.gn | 60 +++ rosen/samples/composer/main.cpp | 368 ++++++++++++++++++ 22 files changed, 1070 insertions(+), 18 deletions(-) create mode 100644 frameworks/surface/include/native_window.h create mode 100644 frameworks/surface/src/native_window.cpp create mode 100644 frameworks/surface/src/surface_utils.cpp create mode 100644 interfaces/innerkits/surface/surface_utils.h create mode 100644 interfaces/innerkits/surface/window.h create mode 100644 rosen/samples/composer/BUILD.gn create mode 100644 rosen/samples/composer/main.cpp diff --git a/frameworks/surface/BUILD.gn b/frameworks/surface/BUILD.gn index bd6fd7748f..a5552282bb 100644 --- a/frameworks/surface/BUILD.gn +++ b/frameworks/surface/BUILD.gn @@ -50,9 +50,11 @@ ohos_shared_library("surface") { "src/buffer_queue_producer.cpp", "src/buffer_utils.cpp", "src/consumer_surface.cpp", + "src/native_window.cpp", "src/producer_surface.cpp", "src/surface.cpp", "src/surface_buffer_impl.cpp", + "src/surface_utils.cpp", ] if (ace_enable_gpu) { diff --git a/frameworks/surface/include/buffer_queue.h b/frameworks/surface/include/buffer_queue.h index e6f02153d6..c0894486d9 100644 --- a/frameworks/surface/include/buffer_queue.h +++ b/frameworks/surface/include/buffer_queue.h @@ -91,10 +91,13 @@ public: int32_t GetDefaultHeight(); GSError SetDefaultUsage(uint32_t usage); uint32_t GetDefaultUsage(); - uint64_t GetUniqueId() const; GSError CleanCache(); + uint64_t GetUniqueId() const; + + void Dump(std::string &result); + private: GSError AllocBuffer(sptr& buffer, const BufferRequestConfig &config); GSError FreeBuffer(sptr& buffer); @@ -109,6 +112,7 @@ private: GSError CheckRequestConfig(const BufferRequestConfig &config); GSError CheckFlushConfig(const BufferFlushConfig &config); + void DumpCache(const std::list &dumpList, std::string &result); int32_t defaultWidth = 0; int32_t defaultHeight = 0; diff --git a/frameworks/surface/include/buffer_queue_consumer.h b/frameworks/surface/include/buffer_queue_consumer.h index c9316c38db..bb3359775d 100644 --- a/frameworks/surface/include/buffer_queue_consumer.h +++ b/frameworks/surface/include/buffer_queue_consumer.h @@ -44,6 +44,7 @@ public: GSError SetDefaultWidthAndHeight(int32_t width, int32_t height); GSError SetDefaultUsage(uint32_t usage); + void Dump(std::string &result) const; private: sptr bufferQueue_ = nullptr; diff --git a/frameworks/surface/include/buffer_queue_producer.h b/frameworks/surface/include/buffer_queue_producer.h index c5b557a039..828cc91a7d 100644 --- a/frameworks/surface/include/buffer_queue_producer.h +++ b/frameworks/surface/include/buffer_queue_producer.h @@ -57,6 +57,7 @@ public: int32_t GetDefaultWidth() override; int32_t GetDefaultHeight() override; uint32_t GetDefaultUsage() override; + uint64_t GetUniqueId() override; GSError CleanCache() override; diff --git a/frameworks/surface/include/consumer_surface.h b/frameworks/surface/include/consumer_surface.h index 9604fb52d3..d4fb8c4109 100644 --- a/frameworks/surface/include/consumer_surface.h +++ b/frameworks/surface/include/consumer_surface.h @@ -75,8 +75,11 @@ public: GSError RegisterConsumerListener(IBufferConsumerListenerClazz *listener) override; GSError RegisterReleaseListener(OnReleaseFunc func) override; GSError UnregisterConsumerListener() override; + uint64_t GetUniqueId() const override; + void Dump(std::string &result) const override; + GSError CleanCache() override; private: diff --git a/frameworks/surface/include/native_window.h b/frameworks/surface/include/native_window.h new file mode 100644 index 0000000000..25689dce23 --- /dev/null +++ b/frameworks/surface/include/native_window.h @@ -0,0 +1,55 @@ +/* + * 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. + */ + +#ifndef BS_NATIVE_WINDOW_H +#define BS_NATIVE_WINDOW_H + +#include "window.h" + +#include +#include +#include + +struct NativeBufferRequestConfig { + int32_t width; + int32_t height; + int32_t stride; // strideAlignment + int32_t format; // PixelFormat + int32_t usage; + int32_t timeout; +}; + +struct NativeWindowMagic : public OHOS::RefBase +{ + NativeWindowMagic(NativeObjectMagic m) : magic(m) {} + virtual ~NativeWindowMagic() {} + NativeObjectMagic magic; +}; + +struct NativeWindow : public NativeWindowMagic { + NativeWindow(); + ~NativeWindow(); + NativeBufferRequestConfig config = {0}; + OHOS::sptr surface; +}; + +struct NativeWindowBuffer : public NativeWindowMagic { + NativeWindowBuffer(); + ~NativeWindowBuffer(); + OHOS::sptr sfbuffer; +}; + + +#endif diff --git a/frameworks/surface/include/producer_surface.h b/frameworks/surface/include/producer_surface.h index 7de8ba5148..f90a5a4ff7 100644 --- a/frameworks/surface/include/producer_surface.h +++ b/frameworks/surface/include/producer_surface.h @@ -78,8 +78,11 @@ public: GSError RegisterConsumerListener(IBufferConsumerListenerClazz *listener) override; GSError RegisterReleaseListener(OnReleaseFunc func) override; GSError UnregisterConsumerListener() override; + uint64_t GetUniqueId() const override; + void Dump(std::string &result) const override {}; + GSError CleanCache() override; private: diff --git a/frameworks/surface/src/buffer_queue.cpp b/frameworks/surface/src/buffer_queue.cpp index c867bf63dc..732b82d6ad 100644 --- a/frameworks/surface/src/buffer_queue.cpp +++ b/frameworks/surface/src/buffer_queue.cpp @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include @@ -41,6 +39,7 @@ static uint64_t GetUniqueIdImpl() static uint64_t id = static_cast(::getpid()) << UNIQUE_ID_OFFSET; return id | counter++; } + BufferQueue::BufferQueue(const std::string &name, bool isShared) : name_(name), uniqueId_(GetUniqueIdImpl()), isShared_(isShared) { @@ -750,4 +749,39 @@ uint64_t BufferQueue::GetUniqueId() const { return uniqueId_; } + +void BufferQueue::DumpCache(const std::list &dumpList, std::string &result) +{ + for (auto it = dumpList.begin(); it != dumpList.end(); it++) { + BufferElement element = bufferQueueCache_.at(*it); + result += " state = " + std::to_string(element.state) + + ", timestamp = " + std::to_string(element.timestamp); + result += ", damageRect = [" + std::to_string(element.damage.x) + ", " + + std::to_string(element.damage.y) + ", " + + std::to_string(element.damage.w) + ", " + + std::to_string(element.damage.h) + "],"; + result += " config = [" + std::to_string(element.config.width) + "x" + + std::to_string(element.config.height) + ":" + + std::to_string(element.config.strideAlignment) + ", " + + std::to_string(element.config.format) +", " + + std::to_string(element.config.usage) + ", " + + std::to_string(element.config.timeout) + "]\n"; + } +} + +void BufferQueue::Dump(std::string &result) +{ + std::lock_guard lockGuard(mutex_); + result.append("-- BufferQueue\n"); + result += " default-size = [" + std::to_string(defaultWidth) + "x" + std::to_string(defaultHeight) + "]\n"; + result += " FIFO = " + std::to_string(queueSize_) + "\n"; + result += " name = " + name_ + "\n"; + + result.append(" FreeList:\n"); + DumpCache(freeList_, result); + result.append(" DirtyList:\n"); + DumpCache(dirtyList_, result); + result.append(" DeletingList:\n"); + DumpCache(deletingList_, result); +} }; // namespace OHOS diff --git a/frameworks/surface/src/buffer_queue_consumer.cpp b/frameworks/surface/src/buffer_queue_consumer.cpp index 4c5a9b4fda..b2b196d07c 100644 --- a/frameworks/surface/src/buffer_queue_consumer.cpp +++ b/frameworks/surface/src/buffer_queue_consumer.cpp @@ -115,4 +115,12 @@ GSError BufferQueueConsumer::SetDefaultUsage(uint32_t usage) } return bufferQueue_->SetDefaultUsage(usage); } + +void BufferQueueConsumer::Dump(std::string &result) const +{ + if (bufferQueue_ == nullptr) { + return; + } + return bufferQueue_->Dump(result); +} } // namespace OHOS diff --git a/frameworks/surface/src/consumer_surface.cpp b/frameworks/surface/src/consumer_surface.cpp index aec563afd5..666fa15faa 100644 --- a/frameworks/surface/src/consumer_surface.cpp +++ b/frameworks/surface/src/consumer_surface.cpp @@ -220,4 +220,9 @@ uint64_t ConsumerSurface::GetUniqueId() const { return producer_->GetUniqueId(); } + +void ConsumerSurface::Dump(std::string &result) const +{ + return consumer_->Dump(result); +} } // namespace OHOS diff --git a/frameworks/surface/src/native_window.cpp b/frameworks/surface/src/native_window.cpp new file mode 100644 index 0000000000..b1af185992 --- /dev/null +++ b/frameworks/surface/src/native_window.cpp @@ -0,0 +1,293 @@ +/* + * 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 "native_window.h" + +#include +#include "surface_type.h" +#include "display_type.h" +#include "buffer_log.h" + + +using namespace OHOS; + +namespace OHOS { +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "NativeWindow" }; +} +} + +struct NativeWindow* CreateNativeWindowFromSurface(void* pSuface) +{ + if (pSuface == nullptr) { + BLOGD("CreateNativeWindowFromSurface pSuface is nullptr"); + return nullptr; + } + NativeWindow* nativeWindow = new NativeWindow(); + nativeWindow->surface = + *reinterpret_cast *>(pSuface); + nativeWindow->config.width = nativeWindow->surface->GetDefaultWidth(); + nativeWindow->config.height = nativeWindow->surface->GetDefaultHeight(); + nativeWindow->config.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA; + nativeWindow->config.format = PIXEL_FMT_RGBA_8888; + nativeWindow->config.stride = 8; // default stride is 8 + + BLOGD("CreateNativeWindowFromSurface width is %{public}d, height is %{public}d", nativeWindow->config.width, \ + nativeWindow->config.height); + NativeObjectReference(nativeWindow); + return nativeWindow; +} + +void DestoryNativeWindow(struct NativeWindow *window) +{ + if (window == nullptr) { + return; + } + // unreference nativewindow object + NativeObjectUnreference(window); +} + +struct NativeWindowBuffer* CreateNativeWindowBufferFromSurfaceBuffer(void* pSurfaceBuffer) +{ + if (pSurfaceBuffer == nullptr) { + return nullptr; + } + NativeWindowBuffer *nwBuffer = new NativeWindowBuffer(); + nwBuffer->sfbuffer = *reinterpret_cast *>(pSurfaceBuffer); + NativeObjectReference(nwBuffer); + return nwBuffer; +} +void DestoryNativeWindowBuffer(struct NativeWindowBuffer* buffer) +{ + if (buffer == nullptr) { + return; + } + NativeObjectUnreference(buffer); +} + +int32_t NativeWindowRequestBuffer(struct NativeWindow *window, + struct NativeWindowBuffer **buffer, int *fenceFd) +{ + if (window == nullptr || buffer == nullptr || fenceFd == nullptr) { + BLOGD("NativeWindowRequestBuffer window or buffer or fenceid is nullptr"); + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + BLOGD("NativeWindow* NativeWindowRequestBuffer width is %{public}d, height is %{public}d", + window->config.width, window->config.height); + OHOS::BufferRequestConfig config = { + .width = window->config.width, + .height = window->config.height, + .strideAlignment = window->config.stride, + .format = window->config.format, + .usage = window->config.usage, + .timeout = window->config.timeout, + }; + OHOS::sptr sfbuffer; + if(window->surface->RequestBuffer(sfbuffer, *fenceFd, config) != OHOS::SurfaceError::SURFACE_ERROR_OK) { + return OHOS::GSERROR_NO_BUFFER; + } + NativeWindowBuffer *nwBuffer = new NativeWindowBuffer(); + nwBuffer->sfbuffer = sfbuffer; + // reference nativewindowbuffer object + NativeObjectReference(nwBuffer); + *buffer = nwBuffer; + return OHOS::GSERROR_OK; +} + +int32_t NativeWindowFlushBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer, + int fenceFd, struct Region region) +{ + if (window == nullptr || buffer == nullptr || window->surface == nullptr) { + BLOGD("NativeWindowFlushBuffer window,buffer is nullptr"); + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + + OHOS::BufferFlushConfig config; + if ((region.rectNumber != 0) && (region.rects != nullptr)) { + config.damage.x = region.rects->x; + config.damage.y = region.rects->y; + config.damage.w = region.rects->w; + config.damage.h = region.rects->h; + config.timestamp = 0; + } else { + config.damage.x = 0; + config.damage.y = 0; + config.damage.w = window->config.width; + config.damage.h = window->config.height; + config.timestamp = 0; + } + + window->surface->FlushBuffer(buffer->sfbuffer, fenceFd, config); + + // unreference nativewindowbuffer object + // NativeObjectUnreference(buffer); + return OHOS::GSERROR_OK; +} + +int32_t NativeWindowCancelBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer) +{ + if (window == nullptr || buffer == nullptr) { + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + window->surface->CancelBuffer(buffer->sfbuffer); + + // unreference nativewindowbuffer object + NativeObjectUnreference(buffer); + return OHOS::GSERROR_OK; +} + +static int32_t InternalHanleNativeWindowOpt(struct NativeWindow *window, int code, va_list args) +{ + switch (code) { + case SET_USAGE: + { + int32_t usage = va_arg(args, int32_t); + window->config.usage = usage; + break; + } + case SET_BUFFER_GEOMETRY: + { + int32_t width = va_arg(args, int32_t); + int32_t height = va_arg(args, int32_t); + window->config.height = height; + window->config.width = width; + break; + } + case SET_FORMAT: + { + int32_t format = va_arg(args, int32_t); + window->config.format = format; + break; + } + case SET_STRIDE: + { + int32_t stride = va_arg(args, int32_t); + window->config.stride = stride; + break; + } + case GET_USAGE: + { + int32_t *value = va_arg(args, int32_t*); + int32_t usage = window->config.usage; + *value = usage; + break; + } + case GET_BUFFER_GEOMETRY: + { + int32_t *height = va_arg(args, int32_t*); + int32_t *width = va_arg(args, int32_t*); + *height = window->config.height; + *width = window->config.width; + break; + } + case GET_FORMAT: + { + int32_t *format = va_arg(args, int32_t*); + *format = window->config.format; + break; + } + case GET_STRIDE: + { + int32_t *stride = va_arg(args, int32_t*); + *stride = window->config.stride; + break; + } + // [TODO] add others + default: + break; + } + return OHOS::GSERROR_OK; +} + +int32_t NativeWindowHandleOpt(struct NativeWindow *window, int code, ...) +{ + if (window == nullptr) { + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + va_list args; + va_start(args, code); + InternalHanleNativeWindowOpt(window, code, args); + va_end(args); + return OHOS::GSERROR_OK; +} + +BufferHandle *GetBufferHandleFromNative(struct NativeWindowBuffer *buffer) +{ + if (buffer == nullptr) { + return nullptr; + } + return buffer->sfbuffer->GetBufferHandle(); +} + +int32_t GetNativeObjectMagic(void *obj) +{ + if (obj == nullptr) { + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + NativeWindowMagic* nativeWindowMagic = reinterpret_cast(obj); + return nativeWindowMagic->magic; +} + +int32_t NativeObjectReference(void *obj) +{ + if (obj == nullptr) { + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + switch(GetNativeObjectMagic(obj)) { + case NATIVE_OBJECT_MAGIC_WINDOW: + case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER: + break; + default: + return OHOS::GSERROR_TYPE_ERROR; + } + OHOS::RefBase *ref = reinterpret_cast(obj); + ref->IncStrongRef(ref); + return OHOS::GSERROR_OK; +} + +int32_t NativeObjectUnreference(void *obj) +{ + if (obj == nullptr) { + return OHOS::GSERROR_INVALID_ARGUMENTS; + } + switch(GetNativeObjectMagic(obj)) { + case NATIVE_OBJECT_MAGIC_WINDOW: + case NATIVE_OBJECT_MAGIC_WINDOW_BUFFER: + break; + default: + return OHOS::GSERROR_TYPE_ERROR; + } + OHOS::RefBase *ref = reinterpret_cast(obj); + ref->DecStrongRef(ref); + return OHOS::GSERROR_OK; +} + +NativeWindow::NativeWindow() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW) +{ + BLOGD("NativeWindow %p", this); +} + +NativeWindow::~NativeWindow() { + BLOGD("~NativeWindow %p", this); +} + +NativeWindowBuffer::~NativeWindowBuffer() { + BLOGD("~NativeWindowBuffer %p", this); +} + +NativeWindowBuffer::NativeWindowBuffer() : NativeWindowMagic(NATIVE_OBJECT_MAGIC_WINDOW_BUFFER) +{ + BLOGD("NativeWindowBuffer %p", this); +} \ No newline at end of file diff --git a/frameworks/surface/src/surface_utils.cpp b/frameworks/surface/src/surface_utils.cpp new file mode 100644 index 0000000000..b4e056fd1b --- /dev/null +++ b/frameworks/surface/src/surface_utils.cpp @@ -0,0 +1,72 @@ +/* + * 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 +#include +#include "buffer_log.h" + +namespace OHOS { +using namespace HiviewDFX; +namespace { +constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0, "SurfaceUtils" }; +} + +SurfaceUtils* SurfaceUtils::GetInstance() +{ + static SurfaceUtils instance; + return &instance; +} + +SurfaceUtils::~SurfaceUtils() +{ + surfaceCache_.clear(); +} + +sptr SurfaceUtils::GetSurface(uint64_t uniqueId) +{ + std::lock_guard lockGuard(mutex_); + if (surfaceCache_.count(uniqueId) == 0) { + BLOGE("Cannot find surface by uniqueId %" PRIu64 ".", uniqueId); + return nullptr; + } + return surfaceCache_[uniqueId]; +} + +SurfaceError SurfaceUtils::Add(uint64_t uniqueId, const sptr &surface) +{ + std::lock_guard lockGuard(mutex_); + if (surface == nullptr) { + BLOGE(" surface is nullptr."); + return SURFACE_ERROR_NULLPTR; + } + if (surfaceCache_.count(uniqueId) == 0) { + surfaceCache_[uniqueId] = surface; + return SURFACE_ERROR_OK; + } + BLOGW("the surface by uniqueId %" PRIu64 " already existed", uniqueId); + return SURFACE_ERROR_OK; +} + +SurfaceError SurfaceUtils::Remove(uint64_t uniqueId) +{ + std::lock_guard lockGuard(mutex_); + if (surfaceCache_.count(uniqueId) == 0) { + BLOGE("Delete failed without surface by uniqueId %" PRIu64 "", uniqueId); + return SURFACE_ERROR_INVALID_OPERATING; + } + surfaceCache_.erase(uniqueId); + return SURFACE_ERROR_OK; +} +} // namespace OHOS diff --git a/interfaces/innerkits/surface/ibuffer_producer.h b/interfaces/innerkits/surface/ibuffer_producer.h index 33f8e561f7..28ffa97efc 100644 --- a/interfaces/innerkits/surface/ibuffer_producer.h +++ b/interfaces/innerkits/surface/ibuffer_producer.h @@ -53,8 +53,8 @@ public: virtual int32_t GetDefaultWidth() = 0; virtual int32_t GetDefaultHeight() = 0; virtual uint32_t GetDefaultUsage() = 0; - virtual uint64_t GetUniqueId() = 0; + virtual uint64_t GetUniqueId() = 0; virtual GSError CleanCache() = 0; virtual GSError RegisterReleaseListener(OnReleaseFunc func) = 0; @@ -76,7 +76,7 @@ protected: BUFFER_PRODUCER_ATTACH_BUFFER = 10, BUFFER_PRODUCER_DETACH_BUFFER = 11, BUFFER_PRODUCER_REGISTER_RELEASE_LISTENER = 12, - BUFFER_PRODUCER_GET_UNIQUE_ID = 12, + BUFFER_PRODUCER_GET_UNIQUE_ID = 13, }; }; } // namespace OHOS diff --git a/interfaces/innerkits/surface/surface.h b/interfaces/innerkits/surface/surface.h index 06a8cf31e0..5a5f3b1ea6 100644 --- a/interfaces/innerkits/surface/surface.h +++ b/interfaces/innerkits/surface/surface.h @@ -82,8 +82,11 @@ public: virtual GSError RegisterConsumerListener(IBufferConsumerListenerClazz *listener) = 0; virtual GSError RegisterReleaseListener(OnReleaseFunc func) = 0; virtual GSError UnregisterConsumerListener() = 0; + virtual uint64_t GetUniqueId() const = 0; + virtual void Dump(std::string &result) const = 0; + virtual GSError CleanCache() = 0; protected: diff --git a/interfaces/innerkits/surface/surface_utils.h b/interfaces/innerkits/surface/surface_utils.h new file mode 100644 index 0000000000..f33a4c3ee1 --- /dev/null +++ b/interfaces/innerkits/surface/surface_utils.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef INTERFACES_INNERKITS_SURFACE_SURFACE_UTILS_H +#define INTERFACES_INNERKITS_SURFACE_SURFACE_UTILS_H + +#include +#include +#include "surface.h" + +namespace OHOS { +class SurfaceUtils { +public: + static SurfaceUtils* GetInstance(); + + // get surface by uniqueId. + sptr GetSurface(uint64_t uniqueId); + // maintenance map with uniqueId and surface. + SurfaceError Add(uint64_t uniqueId, const sptr &surface); + // remove surface by uniqueId. + SurfaceError Remove(uint64_t uniqueId); + +private: + SurfaceUtils() = default; + virtual ~SurfaceUtils(); + + std::unordered_map> surfaceCache_; + std::mutex mutex_; +}; +} // namespace OHOS + +#endif // INTERFACES_INNERKITS_SURFACE_SURFACE_UTILS_H diff --git a/interfaces/innerkits/surface/window.h b/interfaces/innerkits/surface/window.h new file mode 100644 index 0000000000..bd24ceeff8 --- /dev/null +++ b/interfaces/innerkits/surface/window.h @@ -0,0 +1,92 @@ +/* + * 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. + */ + +#ifndef NDK_INCLUDE_NATIVE_WINDOW_H_ +#define NDK_INCLUDE_NATIVE_WINDOW_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct NativeWindow; +struct NativeWindowBuffer; + +#define MKMAGIC(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + ((d) << 0)) + +enum NativeObjectMagic { + NATIVE_OBJECT_MAGIC_WINDOW = MKMAGIC('W', 'I', 'N', 'D'), + NATIVE_OBJECT_MAGIC_WINDOW_BUFFER = MKMAGIC('W', 'B', 'U', 'F'), +}; + +enum NativeObjectType { + NATIVE_OBJECT_WINDOW, + NATIVE_OBJECT_WINDOW_BUFFER, +}; + +struct Region { + struct Rect { + int32_t x; + int32_t y; + uint32_t w; + uint32_t h; + } *rects; // if nullptr, fill the Buffer dirty size by defualt + int32_t rectNumber; // if rectNumber is 0, fill the Buffer dirty size by defualt +}; + +enum NativeWindowOperation { + SET_BUFFER_GEOMETRY, // ([in] int32_t height, [in] int32_t width) + GET_BUFFER_GEOMETRY, // ([out] int32_t *height, [out] int32_t *width) + GET_FORMAT, // ([out] int32_t *format) + SET_FORMAT, // ([in] int32_t format) + GET_USAGE, // ([out] int32_t *usage) + SET_USAGE, // ([in] int32_t usage) + SET_STRIDE, // ([in] int32_t stride) + GET_STRIDE, // ([out] int32_t *stride) + SET_SWAP_INTERVAL, // ([in] int32_t interval) + GET_SWAP_INTERVAL, +}; + +// pSurface type is OHOS::sptr* +struct NativeWindow* CreateNativeWindowFromSurface(void* pSurface); +void DestoryNativeWindow(struct NativeWindow* window); + +// pSurfaceBuffer type is OHOS::sptr* +struct NativeWindowBuffer* CreateNativeWindowBufferFromSurfaceBuffer(void* pSurfaceBuffer); +void DestoryNativeWindowBuffer(struct NativeWindowBuffer* buffer); + +int32_t NativeWindowRequestBuffer(struct NativeWindow *window, /* [out] */ struct NativeWindowBuffer **buffer, + /* [out] get release fence */ int *fenceFd); +int32_t NativeWindowFlushBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer, + int fenceFd, Region region); +int32_t NativeWindowCancelBuffer(struct NativeWindow *window, struct NativeWindowBuffer *buffer); + +// The meaning and quantity of parameters vary according to the code type. +// For details, see the NativeWindowOperation comment. +int32_t NativeWindowHandleOpt(struct NativeWindow *window, int code, ...); +BufferHandle *GetBufferHandleFromNative(struct NativeWindowBuffer *buffer); + +// NativeObject: NativeWindow, NativeWindowBuffer +int32_t NativeObjectReference(void *obj); +int32_t NativeObjectUnreference(void *obj); +int32_t GetNativeObjectMagic(void *obj); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/ohos.build b/ohos.build index 3291049260..1192e828b8 100644 --- a/ohos.build +++ b/ohos.build @@ -15,6 +15,8 @@ "//third_party/weston:default", "//foundation/graphic/standard:default", + "//foundation/graphic/standard/rosen/samples/composer:hello_composer", + "//foundation/graphic/standard/rosen/modules/composer:libcomposer", "//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base", "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client" ], diff --git a/rosen/modules/composer/BUILD.gn b/rosen/modules/composer/BUILD.gn index 721d4c3d39..417900a352 100644 --- a/rosen/modules/composer/BUILD.gn +++ b/rosen/modules/composer/BUILD.gn @@ -60,7 +60,7 @@ ohos_shared_library("libcomposer") { deps = [ "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", - "//drivers/peripheral/display/hal:hdi_display", + "//drivers/peripheral/display/hal:hdi_display_device", "//foundation/graphic/standard:libsurface", "//foundation/graphic/standard/frameworks/vsync:libvsync_module", ] diff --git a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp index 7ce29867a5..6410502b9f 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_backend.cpp @@ -53,7 +53,7 @@ RosenError HdiBackend::RegPrepareComplete(OnPrepareCompleteFunc func, void* data void HdiBackend::Repaint(std::vector &outputs) { - HLOGE("start Repaint"); + HLOGD("start Repaint"); if (device_ == nullptr) { HLOGE("device has not been initialized"); return; @@ -62,6 +62,9 @@ void HdiBackend::Repaint(std::vector &outputs) int32_t ret = DISPLAY_SUCCESS; for (auto &output : outputs) { const std::unordered_map layersMap = output->GetLayers(); + if (layersMap.empty()) { + continue; + } uint32_t screenId = output->GetScreenId(); for (auto iter = layersMap.begin(); iter != layersMap.end(); ++iter) { const LayerPtr &layer = iter->second; @@ -69,7 +72,7 @@ void HdiBackend::Repaint(std::vector &outputs) } bool needFlush = false; - HLOGE("Repaint PrepareScreenLayers"); + HLOGD("Repaint PrepareScreenLayers"); ret = device_->PrepareScreenLayers(screenId, needFlush); if (ret != DISPLAY_SUCCESS) { HLOGE("PrepareScreenLayers failed, ret is %{public}d", ret); @@ -88,11 +91,11 @@ void HdiBackend::Repaint(std::vector &outputs) // return } } - HLOGE("Repaint need to OnPrepareComplete"); + HLOGD("Repaint need to OnPrepareComplete"); OnPrepareComplete(needFlush, output, changedLayerInfos, compTypes); if (needFlush) { - HLOGE("Repaint need to FlushScreen"); + HLOGD("Repaint need to FlushScreen"); if (FlushScreen(screenId, output, changedLayers) != DISPLAY_SUCCESS) { // return [TODO] HLOGE("faile to flushscreen"); @@ -100,13 +103,13 @@ void HdiBackend::Repaint(std::vector &outputs) } sptr fbFence = SyncFence::INVALID_FENCE; - HLOGE("Repaint start to commit"); + HLOGD("Repaint start to commit"); ret = device_->Commit(screenId, fbFence); if (ret != DISPLAY_SUCCESS) { HLOGE("commit failed, ret is %{public}d", ret); // return [TODO] } - HLOGE("Repaint commit end"); + HLOGD("Repaint commit end"); ReleaseLayerBuffer(screenId, layersMap); @@ -148,7 +151,7 @@ int32_t HdiBackend::GetCompChangedLayers(uint32_t screenId, std::vector &changedLayerInfos, std::vector &compTypes) { - HLOGE("OnPrepareComplete begin"); + HLOGD("OnPrepareComplete begin"); struct PrepareCompleteParam param = { .needFlushFramebuffer = needFlush, .layers = changedLayerInfos, @@ -158,7 +161,7 @@ void HdiBackend::OnPrepareComplete(bool needFlush, OutputPtr &output, sptr producerSurface = output->GetProducerSurface(); if (onPrepareCompleteCb_ != nullptr) { - HLOGE("onPrepareCompleteCb_ is not null call it"); + HLOGD("onPrepareCompleteCb_ is not null call it"); onPrepareCompleteCb_(producerSurface, param, onPrepareCompleteCbData_); } } @@ -221,7 +224,7 @@ void HdiBackend::ReleaseLayerBuffer(uint32_t screenId, const std::unordered_map< void HdiBackend::OnHdiBackendHotPlugEvent(uint32_t screenId, bool connected, void *data) { - HLOGE("OnHdiBackendHotPlugEvent screenId [%{public}u] connected [%{public}u]", screenId,connected); + HLOGD("OnHdiBackendHotPlugEvent screenId [%{public}u] connected [%{public}u]", screenId,connected); HdiBackend *hdiBackend = nullptr; if (data != nullptr) { hdiBackend = static_cast(data); @@ -284,7 +287,7 @@ void HdiBackend::OnScreenHotplug(uint32_t screenId, bool connected) RosenError HdiBackend::InitDevice() { - HLOGE("InitDevice begin"); + HLOGD("InitDevice begin"); if (device_ != nullptr) { return ROSEN_ERROR_OK; } @@ -309,7 +312,7 @@ RosenError HdiBackend::InitDevice() } } OnHdiBackendConnected(newScreenId_); - HLOGE("Init HdiDevice succeed"); + HLOGD("Init HdiDevice succeed"); return ROSEN_ERROR_OK; } diff --git a/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp b/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp index 9aa51ddb67..b9d34a7f7b 100644 --- a/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp +++ b/rosen/modules/composer/hdi_backend/src/hdi_layer.cpp @@ -141,7 +141,6 @@ void HdiLayer::ReleaseBuffer() SurfaceError ret = ReleasePrevBuffer(); if (ret != SURFACE_ERROR_OK) { HLOGE("ReleaseBuffer failed, ret is %{public}d", ret); - return; } /* copy currSbuffer to prevSbuffer */ diff --git a/rosen/samples/composer/BUILD.gn b/rosen/samples/composer/BUILD.gn new file mode 100644 index 0000000000..28455a5f06 --- /dev/null +++ b/rosen/samples/composer/BUILD.gn @@ -0,0 +1,60 @@ +# 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. + +import("//build/ohos.gni") + +## Build hello_composer {{{ +config("hello_composer_config") { + visibility = [ ":*" ] + + cflags = [ + "-Wall", + "-Werror", + "-g3", + ] +} + +config("hello_composer_public_config") { + include_dirs = [ + "//foundation/graphic/standard/rosen/modules/composer/hdi_backend/include", + "//drivers/peripheral/display/interfaces/include", + "//foundation/graphic/standard/rosen/include/common", + "//foundation/graphic/standard/interfaces/innerkits/vsync_module", + "//foundation/graphic/standard/interfaces/innerkits/common", + ] +} + +ohos_executable("hello_composer") { + install_enable = true + + sources = [ "main.cpp" ] + + configs = [ ":hello_composer_config" ] + + public_configs = [ ":hello_composer_public_config" ] + + deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", + "//foundation/graphic/standard:libsurface", + "//foundation/graphic/standard:libvsync_client", + "//foundation/graphic/standard/rosen/modules/composer:libcomposer", + ] + + external_deps = [ "ipc:ipc_core" ] + + part_name = "graphic_standard" + subsystem_name = "graphic" +} + +## Build hello_composer }}} + diff --git a/rosen/samples/composer/main.cpp b/rosen/samples/composer/main.cpp new file mode 100644 index 0000000000..6b21593af3 --- /dev/null +++ b/rosen/samples/composer/main.cpp @@ -0,0 +1,368 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "hdi_backend.h" +#include "hdi_layer.h" +#include "hdi_layer_info.h" +#include "hdi_output.h" +#include "hdi_screen.h" + +using namespace OHOS; +using namespace OHOS::Rosen; +using namespace std; + +namespace { +#define LOG(fmt, ...) ::OHOS::HiviewDFX::HiLog::Info( \ + ::OHOS::HiviewDFX::HiLogLabel {LOG_CORE, 0, "Hellocomposer"}, \ + "%{public}s: " fmt, __func__, ##__VA_ARGS__) +} + +class HelloComposer : public IBufferConsumerListenerClazz { +public: + void Init(int32_t width, int32_t height, HdiBackend* backend); + void DoDrawData(void *image, int width, int height); + void Draw(); + void Sync(int64_t, void *data); + void CreatePyhsicalScreen(std::shared_ptr &output); + void DoPrepareCompleted(OHOS::sptr &surface, const struct PrepareCompleteParam ¶m); + virtual void OnBufferAvailable() override; + SurfaceError ProduceBuffer(OHOS::sptr &produceSurface, int width, int height); + bool FillLayer(std::shared_ptr &showLayer, OHOS::sptr &pSurface, + OHOS::sptr &cSurface, uint32_t zorder, IRect &dstRect); + + int32_t freq = 30; + int width = 0; + int height = 0; + int display_w = 480; + int display_h = 960; + +private: + uint32_t currentModeIndex = 0; + std::vector displayModeInfos; + OHOS::sptr pSurface = nullptr; + OHOS::sptr cSurface = nullptr; + OHOS::sptr pSurface1 = nullptr; + OHOS::sptr cSurface1 = nullptr; + std::unique_ptr screen = nullptr; + std::shared_ptr output = nullptr; + std::vector> outputs; + HdiBackend* backend = nullptr; + sptr fbBuffer = nullptr; + bool ready = false; +}; + +void HelloComposer::OnBufferAvailable() +{ +} + +void HelloComposer::DoDrawData(void *image, int width, int height) +{ + static uint32_t value = 0xff0000ff; + + uint32_t *pixel = static_cast(image); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + *pixel++ = value; + } + } +} + +SurfaceError HelloComposer::ProduceBuffer(OHOS::sptr &produceSurface, int width, int height) +{ + OHOS::sptr buffer; + int32_t releaseFence; + BufferRequestConfig config = { + .width = width, + .height = height, + .strideAlignment = 0x8, + .format = PIXEL_FMT_RGBA_8888, + .usage = produceSurface->GetDefaultUsage(), + }; + + SurfaceError ret = produceSurface->RequestBufferWithFence(buffer, releaseFence, config); + if (ret != 0) { + LOG("RequestBuffer failed: %{public}s", SurfaceErrorStr(ret).c_str()); + return ret; + } + if (buffer == nullptr) { + LOG("%s: buffer is nullptr", __func__); + return SURFACE_ERROR_NULLPTR; + } + + auto addr = static_cast(buffer->GetVirAddr()); + LOG("buffer w:%{public}d h:%{public}d stride:%{public}d", buffer->GetWidth(), buffer->GetHeight(), buffer->GetBufferHandle()->stride); + DoDrawData(addr, buffer->GetWidth(), buffer->GetHeight()); + + BufferFlushConfig flushConfig = { + .damage = { + .w = width, + .h = height, + }, + }; + ret = produceSurface->FlushBuffer(buffer, -1, flushConfig); + + LOG("Sync %{public}s", SurfaceErrorStr(ret).c_str()); + return SURFACE_ERROR_OK; +} + +void HelloComposer::Draw() +{ + do { + static int count = 0; + + if (count >= 2000) { + count = 0; + } + + std::vector layerVec; + std::shared_ptr showLayer = HdiLayerInfo::CreateHdiLayerInfo(); + std::shared_ptr showLayer1 = HdiLayerInfo::CreateHdiLayerInfo(); + + if (count <= 50 || count >= 500) { + int32_t zorder = 0; + IRect dstRect; + dstRect.x = 0; // Absolute coordinates, with offset + dstRect.y = 0; + dstRect.w = width; + dstRect.h = height; + if (!FillLayer(showLayer, pSurface, cSurface, zorder, dstRect)) { + continue; + } + layerVec.emplace_back(showLayer); + } + + if (count <= 100 || count >= 1000) { + int zorder1 = 0; + IRect dstRect1; + dstRect1.x = width; // Absolute coordinates, with offset + dstRect1.y = width; + dstRect1.w = width; + dstRect1.h = height; + if (!FillLayer(showLayer1, pSurface1, cSurface1, zorder1, dstRect1)) { + continue; + } + layerVec.emplace_back(showLayer1); + } + LOG("Draw count:%{public}d layer size %{public}d", count, (int32_t)layerVec.size()); + output->SetLayerInfo(layerVec); + backend->Repaint(outputs); + count++; + } while (false); +} + +bool HelloComposer::FillLayer(std::shared_ptr &showLayer, OHOS::sptr &pSurface, + OHOS::sptr &cSurface, uint32_t zorder, IRect &dstRect) +{ + if (ProduceBuffer(pSurface, width, height) != SURFACE_ERROR_OK) { + LOG("Produce cBuffer failed"); + return false; + } + + OHOS::sptr cbuffer = nullptr; + int32_t fence; + int64_t timestamp; + Rect damage; + SurfaceError ret = cSurface->AcquireBuffer(cbuffer, fence, timestamp, damage); + if (ret != SURFACE_ERROR_OK) { + LOG("Acquire cBuffer failed"); + return false; + } + + IRect srcRect; + srcRect.x = 0; + srcRect.y = 0; + srcRect.w = width; + srcRect.h = height; + + LayerAlpha alpha = { .enPixelAlpha = true }; + + showLayer->SetSurface(cSurface); + showLayer->SetBuffer(cbuffer, fence); + showLayer->SetZorder(zorder); + showLayer->SetAlpha(alpha); + showLayer->SetTransform(TransformType::ROTATE_NONE); + showLayer->SetCompositionType(CompositionType::COMPOSITION_DEVICE); + showLayer->SetVisibleRegion(1, srcRect); + showLayer->SetDirtyRegion(srcRect); + showLayer->SetLayerSize(dstRect); + showLayer->SetBlendType(BlendType::BLEND_SRCOVER); + showLayer->SetCropRect(srcRect); + showLayer->SetPreMulti(false); + + return true; +} + +void HelloComposer::Sync(int64_t, void *data) +{ + cout << "hello Sync: ready" << ready << std::endl; + struct OHOS::FrameCallback cb = { + .frequency_ = freq, + .timestamp_ = 0, + .userdata_ = data, + .callback_ = std::bind(&HelloComposer::Sync, this, SYNC_FUNC_ARG), + }; + + OHOS::VsyncError ret = OHOS::VsyncHelper::Current()->RequestFrameCallback(cb); + if (ret) { + LOG("RequestFrameCallback inner %{public}d\n", ret); + } + + if (!ready) { + return; + } + + Draw(); +} + +void HelloComposer::Init(int32_t width, int32_t height, HdiBackend* backend) +{ + this->backend = backend; + + cSurface = Surface::CreateSurfaceAsConsumer(); + cSurface->SetDefaultWidthAndHeight(width, height); + cSurface->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA); + + OHOS::sptr producer = cSurface->GetProducer(); + pSurface = Surface::CreateSurfaceAsProducer(producer); + cSurface->RegisterConsumerListener(this); + LOG("%s: create surface", __func__); + + cSurface1 = Surface::CreateSurfaceAsConsumer(); + cSurface1->SetDefaultWidthAndHeight(width, height); + cSurface1->SetDefaultUsage(HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA); + + OHOS::sptr producer1 = cSurface1->GetProducer(); + pSurface1 = Surface::CreateSurfaceAsProducer(producer1); + cSurface1->RegisterConsumerListener(this); + LOG("%s: create surface1", __func__); + + Sync(0, nullptr); +} + +void HelloComposer::CreatePyhsicalScreen(std::shared_ptr &output) +{ + std::cout << "CreatePyhsicalScreen begin" << std::endl; + screen = HdiScreen::CreateHdiScreen(output->GetScreenId()); + screen->Init(); + screen->GetScreenSuppportedModes(displayModeInfos); + this->output = output; + outputs.push_back(output); + int supportModeNum = displayModeInfos.size(); + if (supportModeNum > 0) { + screen->GetScreenMode(currentModeIndex); + LOG("currentModeIndex:%{public}d", currentModeIndex); + for (int i = 0; i < supportModeNum; i++) { + LOG("modes(%{public}d) %{public}dx%{public}d freq:%{public}d", displayModeInfos[i].id, displayModeInfos[i].width, + displayModeInfos[i].height, displayModeInfos[i].freshRate); + if (displayModeInfos[i].id == static_cast(currentModeIndex)) { + this->freq = 30; + this->display_w = displayModeInfos[i].width; + this->display_h = displayModeInfos[i].height; + break; + } + } + screen->SetScreenPowerStatus(DispPowerStatus::POWER_STATUS_ON); + } + ready = true; + std::cout << "CreatePyhsicalScreen end " << std::endl; +} + +void HelloComposer::DoPrepareCompleted(OHOS::sptr &surface, const struct PrepareCompleteParam ¶m) +{ + if (param.needFlushFramebuffer) { + BufferRequestConfig requestConfig = { + .width = display_w, + .height = display_h, + .strideAlignment = 0x08, + .format = PIXEL_FMT_BGRA_8888, + .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, + .timeout = 0, + }; + + BufferFlushConfig flushConfig = { + .damage = { + .w = display_w, + .h = display_h, + } + }; + int releaseFence = -1; + surface->RequestBufferWithFence(fbBuffer, releaseFence, requestConfig); + auto addr = static_cast(fbBuffer->GetVirAddr()); + + memset_s(addr, fbBuffer->GetSize(), 0, fbBuffer->GetSize()); + surface->FlushBuffer(fbBuffer, -1, flushConfig); + } +} + + +static void OnScreenPlug(std::shared_ptr &output, bool connected, void* data) +{ + LOG("enter OnScreenPlug, connected is %{public}d", connected); + std::cout << "OnScreenPlug begin " << std::endl; + auto* thisPtr = static_cast(data); + if (connected) { + std::cout << "OnScreenPlug connetcted " << std::endl; + thisPtr->CreatePyhsicalScreen(output); + } + //std::cout << "OnScreenPlug not connetected " << std::endl; +} + + +static void OnPrepareCompleted(OHOS::sptr &surface, const struct PrepareCompleteParam ¶m, void* data) +{ + LOG("enter OnPrepareCompleted"); + auto *thisPtr = static_cast (data); + thisPtr->DoPrepareCompleted(surface, param); +} + +int main(int argc, const char *argv[]) +{ + HelloComposer m; + + LOG("start to HdiBackend::GetInstance"); + std::cout << "begin " << std::endl; + HdiBackend* backend = OHOS::Rosen::HdiBackend::GetInstance(); + if (backend == nullptr) { + LOG("HdiBackend::GetInstance fail"); + return -1; + } + std::cout << "RegScreenHotplug " << std::endl; + backend->RegScreenHotplug(OnScreenPlug, &m); + std::cout << "RegPrepareComplete " << std::endl; + backend->RegPrepareComplete(OnPrepareCompleted, &m); + + m.width = 200; + m.height = 200; + // sleep(1); + std::cout << "main EventRunner " << std::endl; + auto runner = OHOS::AppExecFwk::EventRunner::Create(false); + auto handler = std::make_shared(runner); + handler->PostTask(std::bind(&HelloComposer::Init, &m, m.width, m.height, backend)); + runner->Run(); + return 0; +}