mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-24 15:41:02 +00:00
add nativewindow to surface and init hello_composer demo
Signed-off-by: stonesxd <shixindong@huawei.com>
This commit is contained in:
parent
728603a4c7
commit
1e5d1f2fe5
@ -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) {
|
||||
|
@ -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<SurfaceBufferImpl>& buffer, const BufferRequestConfig &config);
|
||||
GSError FreeBuffer(sptr<SurfaceBufferImpl>& buffer);
|
||||
@ -109,6 +112,7 @@ private:
|
||||
|
||||
GSError CheckRequestConfig(const BufferRequestConfig &config);
|
||||
GSError CheckFlushConfig(const BufferFlushConfig &config);
|
||||
void DumpCache(const std::list<int32_t> &dumpList, std::string &result);
|
||||
|
||||
int32_t defaultWidth = 0;
|
||||
int32_t defaultHeight = 0;
|
||||
|
@ -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> bufferQueue_ = nullptr;
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
int32_t GetDefaultWidth() override;
|
||||
int32_t GetDefaultHeight() override;
|
||||
uint32_t GetDefaultUsage() override;
|
||||
|
||||
uint64_t GetUniqueId() override;
|
||||
|
||||
GSError CleanCache() override;
|
||||
|
@ -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:
|
||||
|
55
frameworks/surface/include/native_window.h
Normal file
55
frameworks/surface/include/native_window.h
Normal file
@ -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 <refbase.h>
|
||||
#include <surface.h>
|
||||
#include <surface_buffer.h>
|
||||
|
||||
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<OHOS::Surface> surface;
|
||||
};
|
||||
|
||||
struct NativeWindowBuffer : public NativeWindowMagic {
|
||||
NativeWindowBuffer();
|
||||
~NativeWindowBuffer();
|
||||
OHOS::sptr<OHOS::SurfaceBuffer> sfbuffer;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -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:
|
||||
|
@ -18,8 +18,6 @@
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -41,6 +39,7 @@ static uint64_t GetUniqueIdImpl()
|
||||
static uint64_t id = static_cast<uint64_t>(::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<int32_t> &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<std::mutex> 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
293
frameworks/surface/src/native_window.cpp
Normal file
293
frameworks/surface/src/native_window.cpp
Normal file
@ -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 <map>
|
||||
#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<OHOS::sptr<OHOS::Surface> *>(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<OHOS::sptr<OHOS::SurfaceBuffer> *>(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<OHOS::SurfaceBuffer> 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<NativeWindowMagic *>(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<OHOS::RefBase *>(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<OHOS::RefBase *>(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);
|
||||
}
|
72
frameworks/surface/src/surface_utils.cpp
Normal file
72
frameworks/surface/src/surface_utils.cpp
Normal file
@ -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 <surface_utils.h>
|
||||
#include <cinttypes>
|
||||
#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<Surface> SurfaceUtils::GetSurface(uint64_t uniqueId)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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> &surface)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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
|
@ -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
|
||||
|
@ -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:
|
||||
|
44
interfaces/innerkits/surface/surface_utils.h
Normal file
44
interfaces/innerkits/surface/surface_utils.h
Normal file
@ -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 <unordered_map>
|
||||
#include <mutex>
|
||||
#include "surface.h"
|
||||
|
||||
namespace OHOS {
|
||||
class SurfaceUtils {
|
||||
public:
|
||||
static SurfaceUtils* GetInstance();
|
||||
|
||||
// get surface by uniqueId.
|
||||
sptr<Surface> GetSurface(uint64_t uniqueId);
|
||||
// maintenance map with uniqueId and surface.
|
||||
SurfaceError Add(uint64_t uniqueId, const sptr<Surface> &surface);
|
||||
// remove surface by uniqueId.
|
||||
SurfaceError Remove(uint64_t uniqueId);
|
||||
|
||||
private:
|
||||
SurfaceUtils() = default;
|
||||
virtual ~SurfaceUtils();
|
||||
|
||||
std::unordered_map<uint64_t, sptr<Surface>> surfaceCache_;
|
||||
std::mutex mutex_;
|
||||
};
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // INTERFACES_INNERKITS_SURFACE_SURFACE_UTILS_H
|
92
interfaces/innerkits/surface/window.h
Normal file
92
interfaces/innerkits/surface/window.h
Normal file
@ -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 <stdint.h>
|
||||
#include <buffer_handle.h>
|
||||
|
||||
#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<OHOS::Surface>*
|
||||
struct NativeWindow* CreateNativeWindowFromSurface(void* pSurface);
|
||||
void DestoryNativeWindow(struct NativeWindow* window);
|
||||
|
||||
// pSurfaceBuffer type is OHOS::sptr<OHOS::SurfaceBuffer>*
|
||||
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
|
@ -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"
|
||||
],
|
||||
|
@ -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",
|
||||
]
|
||||
|
@ -53,7 +53,7 @@ RosenError HdiBackend::RegPrepareComplete(OnPrepareCompleteFunc func, void* data
|
||||
|
||||
void HdiBackend::Repaint(std::vector<OutputPtr> &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<OutputPtr> &outputs)
|
||||
int32_t ret = DISPLAY_SUCCESS;
|
||||
for (auto &output : outputs) {
|
||||
const std::unordered_map<uint32_t, LayerPtr> 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<OutputPtr> &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<OutputPtr> &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<OutputPtr> &outputs)
|
||||
}
|
||||
|
||||
sptr<SyncFence> 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<LayerPtr
|
||||
void HdiBackend::OnPrepareComplete(bool needFlush, OutputPtr &output,
|
||||
std::vector<LayerInfoPtr> &changedLayerInfos, std::vector<CompositionType> &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<Surface> 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<HdiBackend *>(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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
60
rosen/samples/composer/BUILD.gn
Normal file
60
rosen/samples/composer/BUILD.gn
Normal file
@ -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 }}}
|
||||
|
368
rosen/samples/composer/main.cpp
Normal file
368
rosen/samples/composer/main.cpp
Normal file
@ -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 <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <securec.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <vsync_helper.h>
|
||||
#include <display_type.h>
|
||||
#include <surface.h>
|
||||
#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<HdiOutput> &output);
|
||||
void DoPrepareCompleted(OHOS::sptr<Surface> &surface, const struct PrepareCompleteParam ¶m);
|
||||
virtual void OnBufferAvailable() override;
|
||||
SurfaceError ProduceBuffer(OHOS::sptr<Surface> &produceSurface, int width, int height);
|
||||
bool FillLayer(std::shared_ptr<HdiLayerInfo> &showLayer, OHOS::sptr<Surface> &pSurface,
|
||||
OHOS::sptr<Surface> &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<DisplayModeInfo> displayModeInfos;
|
||||
OHOS::sptr<Surface> pSurface = nullptr;
|
||||
OHOS::sptr<Surface> cSurface = nullptr;
|
||||
OHOS::sptr<Surface> pSurface1 = nullptr;
|
||||
OHOS::sptr<Surface> cSurface1 = nullptr;
|
||||
std::unique_ptr<HdiScreen> screen = nullptr;
|
||||
std::shared_ptr<HdiOutput> output = nullptr;
|
||||
std::vector<std::shared_ptr<HdiOutput>> outputs;
|
||||
HdiBackend* backend = nullptr;
|
||||
sptr<SurfaceBuffer> 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<uint32_t *>(image);
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
*pixel++ = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceError HelloComposer::ProduceBuffer(OHOS::sptr<Surface> &produceSurface, int width, int height)
|
||||
{
|
||||
OHOS::sptr<SurfaceBuffer> 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<uint8_t *>(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<LayerInfoPtr> layerVec;
|
||||
std::shared_ptr<HdiLayerInfo> showLayer = HdiLayerInfo::CreateHdiLayerInfo();
|
||||
std::shared_ptr<HdiLayerInfo> 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<HdiLayerInfo> &showLayer, OHOS::sptr<Surface> &pSurface,
|
||||
OHOS::sptr<Surface> &cSurface, uint32_t zorder, IRect &dstRect)
|
||||
{
|
||||
if (ProduceBuffer(pSurface, width, height) != SURFACE_ERROR_OK) {
|
||||
LOG("Produce cBuffer failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
OHOS::sptr<SurfaceBuffer> 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<IBufferProducer> 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<IBufferProducer> producer1 = cSurface1->GetProducer();
|
||||
pSurface1 = Surface::CreateSurfaceAsProducer(producer1);
|
||||
cSurface1->RegisterConsumerListener(this);
|
||||
LOG("%s: create surface1", __func__);
|
||||
|
||||
Sync(0, nullptr);
|
||||
}
|
||||
|
||||
void HelloComposer::CreatePyhsicalScreen(std::shared_ptr<HdiOutput> &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<int32_t>(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> &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<uint8_t *>(fbBuffer->GetVirAddr());
|
||||
|
||||
memset_s(addr, fbBuffer->GetSize(), 0, fbBuffer->GetSize());
|
||||
surface->FlushBuffer(fbBuffer, -1, flushConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void OnScreenPlug(std::shared_ptr<HdiOutput> &output, bool connected, void* data)
|
||||
{
|
||||
LOG("enter OnScreenPlug, connected is %{public}d", connected);
|
||||
std::cout << "OnScreenPlug begin " << std::endl;
|
||||
auto* thisPtr = static_cast<HelloComposer *>(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> &surface, const struct PrepareCompleteParam ¶m, void* data)
|
||||
{
|
||||
LOG("enter OnPrepareCompleted");
|
||||
auto *thisPtr = static_cast<HelloComposer *> (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<OHOS::AppExecFwk::EventHandler>(runner);
|
||||
handler->PostTask(std::bind(&HelloComposer::Init, &m, m.width, m.height, backend));
|
||||
runner->Run();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user