/*
* Copyright (c) 2023 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 "rs_surface_gpu.h"
#include <memory>
#include <QuartzCore/CALayer.h>
#include <UIKit/UIKit.h>
#include "platform/common/rs_log.h"
#include "rs_surface_frame_ios.h"
#include "rs_surface_platform_texture_ios.h"
#include "rs_surface_texture_ios.h"
namespace OHOS {
namespace Rosen {
RSSurfaceGPU::RSSurfaceGPU(void* layer)
{
[static_cast<CAEAGLLayer*>(layer_) release];
layer_ = [layer retain];
}
RSSurfaceGPU::~RSSurfaceGPU()
{
ROSEN_LOGD("RSSurfaceGPU::release");
if (renderContext_ != nullptr) {
renderContext_->DestroyEGLSurface(layer_);
}
[static_cast<CAEAGLLayer*>(layer_) release];
layer_ = nullptr;
}
bool RSSurfaceGPU::IsValid() const
{
return layer_ != nullptr && renderContext_ != nullptr;
}
std::unique_ptr<RSSurfaceFrame> RSSurfaceGPU::RequestFrame(
int32_t width, int32_t height, uint64_t uiTimestamp, bool useAFBC, bool isProtected)
{
if (!IsValid()) {
ROSEN_LOGE("RSSurfaceGPU::RequestFrame, layer_ is nullptr");
return nullptr;
}
if (!SetupGrContext()) {
return nullptr;
}
if (!renderContext_->CreateEGLSurface(layer_)) {
return nullptr;
}
renderContext_->MakeCurrent(layer_, nullptr);
auto frame = std::make_unique<RSSurfaceFrameIOS>(width, height);
frame->SetRenderContext(renderContext_);
frame->CreateSurface();
return frame;
}
bool RSSurfaceGPU::FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame, uint64_t uiTimestamp)
{
if (frame == nullptr) {
ROSEN_LOGE("RSSurfaceGPU::FlushFrame frame is nullptr");
return false;
}
if (!IsValid()) {
ROSEN_LOGE("RSSurfaceGPU::FlushFrame, layer_ or renderContent_ is nullptr");
return false;
}
/* gpu render flush */
renderContext_->MakeCurrent(layer_, nullptr);
renderContext_->RenderFrame();
renderContext_->SwapBuffers(nullptr);
if (auto grContext = renderContext_->GetDrGPUContext()) {
grContext->PurgeUnlockedResources(true);
}
return true;
}
std::shared_ptr<RenderContext> RSSurfaceGPU::GetRenderContext()
{
return renderContext_;
}
void RSSurfaceGPU::SetRenderContext(std::shared_ptr<RenderContext> context)
{
if (renderContext_ != context) {
if (renderContext_ != nullptr) {
renderContext_->DeleteSurface();
}
renderContext_ = std::static_pointer_cast<RenderContextGL>(context);
if (renderContext_ != nullptr) {
renderContext_->AddSurface();
}
}
}
bool RSSurfaceGPU::SetupGrContext()
{
if (renderContext_) {
renderContext_->Init();
renderContext_->SetUpGpuContext();
}
return true;
}
uint32_t RSSurfaceGPU::GetQueueSize() const
{
/* cache buffer count */
return 0x3;
}
GraphicColorGamut RSSurfaceGPU::GetColorSpace() const
{
if (renderContext_ == nullptr) {
ROSEN_LOGE("RSSurfaceGPU::GetColorSpace renderContext_ is nullptr");
return GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
}
return renderContext_->GetColorSpace();
}
void RSSurfaceGPU::SetColorSpace(GraphicColorGamut colorSpace)
{
if (renderContext_ == nullptr) {
ROSEN_LOGE("RSSurfaceGPU::SetColorSpace renderContext_ is nullptr");
return;
}
renderContext_->SetColorSpace(colorSpace);
}
RSSurfaceExtPtr RSSurfaceGPU::CreateSurfaceExt(const RSSurfaceExtConfig& config)
{
ROSEN_LOGD("RSSurfaceGPU::CreateSurfaceExt");
switch(config.type) {
case RSSurfaceExtType::SURFACE_TEXTURE: {
if (texture_ == nullptr) {
texture_ = std::dynamic_pointer_cast<RSSurfaceExt>(std::make_shared<RSSurfaceTextureIOS>(config));
}
return texture_;
}
case RSSurfaceExtType::SURFACE_PLATFORM_TEXTURE: {
if (texture_ == nullptr) {
auto texture = std::make_shared<RSSurfacePlatformTextureIOS>(config);
texture_ = std::dynamic_pointer_cast<RSSurfaceExt>(texture);
}
return texture_;
}
default:
return nullptr;
}
}
RSSurfaceExtPtr RSSurfaceGPU::GetSurfaceExt(const RSSurfaceExtConfig& config)
{
switch(config.type) {
case RSSurfaceExtType::SURFACE_TEXTURE: {
return texture_;
}
case RSSurfaceExtType::SURFACE_PLATFORM_TEXTURE: {
return texture_;
}
default:
return nullptr;
}
}
} // namespace Rosen
} // namespace OHOS