diff --git a/frameworks/innerkitsimpl/common/src/pixel_map.cpp b/frameworks/innerkitsimpl/common/src/pixel_map.cpp index 8fb43e94b3dda8f4d02d66dd42cca7a11ef0e45a..f50f71cb307d3bbc6ca7f5bfa483bcdb6d662460 100644 --- a/frameworks/innerkitsimpl/common/src/pixel_map.cpp +++ b/frameworks/innerkitsimpl/common/src/pixel_map.cpp @@ -531,7 +531,7 @@ void PixelMap::UpdatePixelsAlphaType() return; } - uint8_t pixelBytes = GetPixelBytes(); + int32_t pixelBytes = GetPixelBytes(); int32_t stride = GetRowStride(); int32_t rowBytes = GetRowBytes(); diff --git a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_common.h b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_common.h index 78bcbccc8f8a2e1168884573829e3184d3e595ac..dac769d99807a545a386ee5ea5affd0fe0d82f49 100644 --- a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_common.h +++ b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 @@ -162,9 +162,9 @@ struct GlImageInfo { void *outdata = nullptr; }; typedef struct GPUTransformData { - float rotateDegreeZ; + float rotateDegreeZ = 0.0f; GlCommon::Mat4 rotateTrans; - TransformationType transformationType; + TransformationType transformationType = TransformationType::SCALE; GLenum glFormat = GL_RGBA; bool isDma = false; GlImageInfo sourceInfo_; diff --git a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_context.h b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_context.h index 184d16079ead33e9e3d11758e72d9e2fef6662dc..734a8b6e2e0c7ab0d807e3210302d2da10ea7443 100644 --- a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_context.h +++ b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_context.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 diff --git a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_post_proc_program.h b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_post_proc_program.h index 05fb2464f87e550d491bf1d2967ff761bc04852d..65b1c4cf1fffd1fa03e31cc12043c393532edd05 100644 --- a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_post_proc_program.h +++ b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_post_proc_program.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 diff --git a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_shader.h b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_shader.h index 0279f72d2d77fa969bc66c494abc282f94e4ce07..ab5c18b9186dbe867be8fe402749ddebd9ecc5a0 100644 --- a/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_shader.h +++ b/frameworks/innerkitsimpl/egl_image/include/pixel_map_gl_shader.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 diff --git a/frameworks/innerkitsimpl/egl_image/include/pixel_map_program_manager.h b/frameworks/innerkitsimpl/egl_image/include/pixel_map_program_manager.h index 4eaeaa675ad245549d28c1af3893ef12c1d1b52f..0f2532594b839f0d46e228209893d1be3dd3629a 100644 --- a/frameworks/innerkitsimpl/egl_image/include/pixel_map_program_manager.h +++ b/frameworks/innerkitsimpl/egl_image/include/pixel_map_program_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 diff --git a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_context.cpp b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_context.cpp index 3a15a67fe918196b54e08c0f353438519582920d..ea3e2e886ef4c048af0b81feab00baf725936f62 100644 --- a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_context.cpp +++ b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_context.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 diff --git a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_post_proc_program.cpp b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_post_proc_program.cpp index d79490f84e51401860968809178f4e31c051eadc..8f3fa02ac7d6a46516238a28e8dda97a9e73dbb3 100644 --- a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_post_proc_program.cpp +++ b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_post_proc_program.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2024 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 @@ -56,7 +56,6 @@ PixelMapGLPostProcProgram::PixelMapGLPostProcProgram() PixelMapGLPostProcProgram::~PixelMapGLPostProcProgram() noexcept { Clear(); - IMAGE_LOGE("slr_gpu ~PixelMapGLPostProcProgram()"); } void PixelMapGLPostProcProgram::SetGPUTransformData(GPUTransformData &transformData) @@ -128,7 +127,7 @@ bool PixelMapGLPostProcProgram::Init() bool PixelMapGLPostProcProgram::CreateNormalImage(const uint8_t *data, GLuint &imageTexId) { - const Size &sourceSize = transformData_.sourceInfo_.size; + const Size &srcSize = transformData_.sourceInfo_.size; int perPixelSize = transformData_.sourceInfo_.pixelBytes; if (data == nullptr) { return false; @@ -141,32 +140,31 @@ bool PixelMapGLPostProcProgram::CreateNormalImage(const uint8_t *data, GLuint &i glBindTexture(GL_TEXTURE_2D, imageTexId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sourceSize.width, sourceSize.height, 0, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, srcSize.width, srcSize.height, 0, transformData_.glFormat, GL_UNSIGNED_BYTE, NULL); - if (perPixelSize * sourceSize.width == transformData_.sourceInfo_.stride) { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, sourceSize.width, sourceSize.height, + if (perPixelSize * srcSize.width == transformData_.sourceInfo_.stride) { + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, srcSize.width, srcSize.height, transformData_.glFormat, GL_UNSIGNED_BYTE, data); } else { GLuint pbo = 0; glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER, - sourceSize.width * sourceSize.height * perPixelSize, NULL, GL_STREAM_DRAW); - char *mapPointer = (char *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, - sourceSize.width * sourceSize.height * perPixelSize, GL_MAP_WRITE_BIT); - if (mapPointer == NULL) { + srcSize.width * srcSize.height * perPixelSize, NULL, GL_STREAM_DRAW); + char *mapPtr = (char *)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, + srcSize.width * srcSize.height * perPixelSize, GL_MAP_WRITE_BIT); + if (mapPtr == NULL) { return false; } - for (int i = 0; i < sourceSize.height; i++) { - if (memcpy_s(mapPointer + sourceSize.width * perPixelSize * i, - sourceSize.width * perPixelSize * (sourceSize.height - i), - data + perPixelSize * i, sourceSize.width * perPixelSize) != 0) { + for (int i = 0; i < srcSize.height; i++) { + if (memcpy_s(mapPtr + srcSize.width * perPixelSize * i, srcSize.width * perPixelSize * (srcSize.height - i), + data + perPixelSize * i, srcSize.width * perPixelSize) != 0) { IMAGE_LOGE("slr_gpu %{public}s memcpy_s failed", __func__); return false; } } glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sourceSize.width, sourceSize.height, 0, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, srcSize.width, srcSize.height, 0, transformData_.glFormat, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteBuffers(1, &pbo); @@ -218,7 +216,7 @@ bool PixelMapGLPostProcProgram::CreateEGLImage(OHNativeWindowBuffer *nativeBuffe bool PixelMapGLPostProcProgram::UseEGLImageCreateNormalImage(GLuint &imageTexId) { GLuint eglImageTexId = imageTexId; - Size &sourceSize = transformData_.sourceInfo_.size; + Size &srcSize = transformData_.sourceInfo_.size; GLuint tempFbo[NUM_2]; glGenFramebuffers(NUM_2, tempFbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, tempFbo[0]); @@ -229,15 +227,15 @@ bool PixelMapGLPostProcProgram::UseEGLImageCreateNormalImage(GLuint &imageTexId) glBindTexture(GL_TEXTURE_2D, imageTexId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sourceSize.width, sourceSize.height, 0, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, srcSize.width, srcSize.height, 0, transformData_.glFormat, GL_UNSIGNED_BYTE, NULL); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tempFbo[1]); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, imageTexId, 0); IMAGE_LOGD("drawfbo status %{public}x", glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); - glBlitFramebuffer(0, 0, sourceSize.width, sourceSize.height, 0, 0, sourceSize.width, - sourceSize.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBlitFramebuffer(0, 0, srcSize.width, srcSize.height, 0, 0, srcSize.width, + srcSize.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); eglDestroyImageKHR(renderContext_->GetEGLDisplay(), eglImage_); glDeleteTextures(1, &eglImageTexId); glDeleteFramebuffers(NUM_2, tempFbo); @@ -291,6 +289,13 @@ bool PixelMapGLPostProcProgram::BuildProcTexture(bool needThumb, bool needUpload } } else { void *surfaceBuffer = transformData_.sourceInfo_.context; + if (surfaceBuffer == nullptr) { + return false; + } + SurfaceBuffer *surface = static_cast(surfaceBuffer); + if (surface && (surface->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) { + surface->FlushCache(); + } nativeBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&surfaceBuffer); if (!CreateEGLImage(nativeBuffer, eglImage_, readTexId)) { DestroyNativeWindowBuffer(nativeBuffer); @@ -414,15 +419,15 @@ bool PixelMapGLPostProcProgram::ReadEndData(char *targetData, GLuint &writeTexId glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo); glBufferData(GL_PIXEL_PACK_BUFFER, targetSize.width * targetSize.height * NUM_4, NULL, GL_STREAM_READ); glReadPixels(0, 0, targetSize.width, targetSize.height, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - char *mapPointer = (char *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, + char *mapPtr = (char *)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, targetSize.width * targetSize.height * NUM_4, GL_MAP_READ_BIT); - if (mapPointer == NULL) { + if (mapPtr == NULL) { return false; } for (int i = 0; i < targetSize.height; i++) { if (memcpy_s(targetData + transformData_.targetInfo_.stride * i, targetSize.width * NUM_4 * (targetSize.height - i), - mapPointer + targetSize.width * NUM_4 * i, targetSize.width * NUM_4) != 0) { + mapPtr + targetSize.width * NUM_4 * i, targetSize.width * NUM_4) != 0) { IMAGE_LOGE("slr_gpu %{public}s memcpy_s fail", __func__); return false; } @@ -464,6 +469,10 @@ bool PixelMapGLPostProcProgram::ReadEndDMAData(void *surfaceBuffer, GLuint &writ glDeleteFramebuffers(1, &endFbo); DestroyNativeWindowBuffer(nativeBuffer); glFinish(); + SurfaceBuffer* surface = static_cast(surfaceBuffer); + if (surface && (surface->GetUsage() & BUFFER_USAGE_MEM_MMZ_CACHE)) { + surface->InvalidateCache(); + } GLenum err = glGetError(); if (err != GL_NO_ERROR) { IMAGE_LOGE("slr_gpu %{public}s failed gl error: %{public}x", __func__, err); diff --git a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_shader.cpp b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_shader.cpp index bf40a6cb28b14e11e6557db05d6c30a3d8bbd237..c6f38ff7d2b75fa4d7814c62a191bd8c5e38fc5f 100644 --- a/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_shader.cpp +++ b/frameworks/innerkitsimpl/egl_image/src/pixel_map_gl_shader.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 @@ -16,7 +16,6 @@ #include "pixel_map_gl_shader.h" #include -#include #include #include #include @@ -55,52 +54,43 @@ unsigned char *LapShader::shaderBinary_ = nullptr; GLenum LapShader::binaryFormat_ = 0; GLuint LapShader::binarySize_ = 0; -float GeSLRFactor(float x, int a) +float geSLRFactor(float x, int a) { if (x >= a || x < -a) { return 0.0f; } if (std::abs(x) < 1e-16) { - return 0.0f; + return 1.0f; } + x *= PI; - if (std::abs(x * x) < 1e-6 || x * x == 0.0f || - std::abs(a) < 1e-6 || a == 0.0f) { - return 0.0f; - } return a * std::sin(x) * std::sin(x / a) / (x * x); } static std::shared_ptr getWeights(float coeff, int n) { - if (std::abs(coeff) < 1e-6 || coeff == 0.0f) { - coeff = 1.0f; - } float tao = 1.0f / coeff; int a = std::max(2, static_cast(std::floor(tao))); int width = 2 * a; width = std::min(width, MAX_SLR_WIN_SIZE); - std::shared_ptr weights = std::make_shared(n * MAX_SLR_WIN_SIZE); + std::shared_ptr weights(new float[n * MAX_SLR_WIN_SIZE], std::default_delete()); for (auto i = 0; i < n; i++) { - if (std::abs(coeff) < 1e-6 || coeff == 0.0f) { - coeff = 1.0f; - } float eta_i = (i + 0.5) / coeff - 0.5; int eta_i_int = std::floor(eta_i); float sum = 0; int k = eta_i_int - a + 1; for (auto j = 0; j < width; ++j) { - float f = GeSLRFactor(coeff * (eta_i - (k + j)), a); + float f = geSLRFactor(coeff * (eta_i - (k + j)), a); weights[i * MAX_SLR_WIN_SIZE + j] = f; sum += f; } for (auto j = 0; j < width; ++j) { weights[i * MAX_SLR_WIN_SIZE + j] /= sum; } - for (auto h = width; h < MAX_SLR_WIN_SIZE; ++h) { - weights[i * MAX_SLR_WIN_SIZE + h] = 0; + for (auto l = width; l < MAX_SLR_WIN_SIZE; ++l) { + weights[i * MAX_SLR_WIN_SIZE + l] = 0; } } return weights; @@ -415,38 +405,39 @@ bool RotateShader::Clear() return Shader::Clear(); } +static const char vShaderStr[] = + "#version 320 es\n" + "layout (location = 0) in vec3 position;\n" + "layout (location = 1) in vec2 texCoords;\n" + "uniform mat4 transform;\n" + "uniform vec2 texClipRatio;\n" + "out vec2 vTexCoords;\n" + "void main()\n" + "{\n" + " gl_Position = transform * vec4(position.x, position.y, position.z, 1.0f);\n" + " vTexCoords = texCoords * texClipRatio + 0.5 * (vec2(1.0, 1.0) - texClipRatio);\n" + "}\n"; +static const char fShaderStr[] = + "#version 320 es\n" + "#extension GL_OES_EGL_image_external_essl3 : require\n" + "precision mediump float;\n" + "in vec2 vTexCoords;\n" + "layout (binding = 0) uniform samplerExternalOES nativeTexture;\n" + "layout (binding = 1) uniform sampler2D normalTexture;\n" + "uniform int useNative;\n" + "out vec4 vFragColor;\n" + "void main()\n" + "{\n" + " if (useNative == 1) {\n" + " vFragColor = texture(nativeTexture, vTexCoords);\n" + " } else {\n" + " vFragColor = texture(normalTexture, vTexCoords);\n" + " }\n" + "}\n"; + bool RotateShader::Build() { ImageTrace imageTrace("RotateShader::Build"); - static const char vShaderStr[] = - "#version 320 es\n" - "layout (location = 0) in vec3 position;\n" - "layout (location = 1) in vec2 texCoords;\n" - "uniform mat4 transform;\n" - "uniform vec2 texClipRatio;\n" - "out vec2 vTexCoords;\n" - "void main()\n" - "{\n" - " gl_Position = transform * vec4(position.x, position.y, position.z, 1.0f);\n" - " vTexCoords = texCoords * texClipRatio + 0.5 * (vec2(1.0, 1.0) - texClipRatio);\n" - "}\n"; - static const char fShaderStr[] = - "#version 320 es\n" - "#extension GL_OES_EGL_image_external_essl3 : require\n" - "precision mediump float;\n" - "in vec2 vTexCoords;\n" - "layout (binding = 0) uniform samplerExternalOES nativeTexture;\n" - "layout (binding = 1) uniform sampler2D normalTexture;\n" - "uniform int useNative;\n" - "out vec4 vFragColor;\n" - "void main()\n" - "{\n" - " if (useNative == 1) {\n" - " vFragColor = texture(nativeTexture, vTexCoords);\n" - " } else {\n" - " vFragColor = texture(normalTexture, vTexCoords);\n" - " }\n" - "}\n"; vShader_ = loadShader(GL_VERTEX_SHADER, vShaderStr); fShader_ = loadShader(GL_FRAGMENT_SHADER, fShaderStr); if (vShader_ == 0 || fShader_ == 0) { @@ -575,53 +566,54 @@ bool SLRShader::Clear() return Shader::Clear(); } -bool SLRShader::Build() -{ - static const char vSlrShaderStr[] = - "#version 320 es\n" - "layout (location = 0) in vec3 position;\n" - "layout (location = 1) in vec2 texCoords;\n" - "uniform mat4 transform;\n" - "uniform vec2 texClipRatio;\n" - "out vec2 vTexCoords;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(position.x, position.y, position.z, 1.0f);\n" - " vTexCoords = texCoords;\n" - "}\n"; - static const char fSlrShaderStr[] = R"(#version 320 es - precision mediump float; - in vec2 vTexCoords; - layout (binding = 1) uniform sampler2D utexture; - layout (binding = 2) uniform sampler2D utexturew; - layout (binding = 3) uniform sampler2D utextureh; - uniform ivec2 srcSize; - uniform ivec2 dstSize; - uniform ivec2 slr_a; - uniform ivec2 slr_max; - uniform vec2 slr_coeff; - uniform vec2 slr_coeff_tao; - out vec4 FragColor; - void main() - { - ivec2 tex_size = textureSize(utexture, 0); - vec2 eta = (gl_FragCoord.xy + vec2(0.5)) * slr_coeff_tao - vec2(0.5); - ivec2 eta_c = ivec2(floor(eta.x), floor(eta.y)); - ivec2 coord_s = ivec2(eta_c.x - slr_a.x + 1, eta_c.y - slr_a.y + 1); - vec4 color = vec4(0, 0, 0, 0); - for (int i = 0; i < slr_max.y; i++) { - float w_i = texelFetch(utextureh, ivec2(i, gl_FragCoord.y), 0).r; - vec4 t = vec4(0, 0, 0, 0); - for (int j = 0; j < slr_max.x; j++) { - float w_j = texelFetch(utexturew, ivec2(j, gl_FragCoord.x), 0).r; - ivec2 coord = clamp(coord_s + ivec2(j, i), ivec2(0), tex_size - ivec2(1)); - t += w_j * texelFetch(utexture, coord, 0); - } - color += t * w_i; +static const char vSlrShaderStr[] = + "#version 320 es\n" + "layout (location = 0) in vec3 position;\n" + "layout (location = 1) in vec2 texCoords;\n" + "uniform mat4 transform;\n" + "uniform vec2 texClipRatio;\n" + "out vec2 vTexCoords;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.x, position.y, position.z, 1.0f);\n" + " vTexCoords = texCoords;\n" + "}\n"; +static const char fSlrShaderStr[] = R"(#version 320 es + precision mediump float; + in vec2 vTexCoords; + layout (binding = 1) uniform sampler2D utexture; + layout (binding = 2) uniform sampler2D utexturew; + layout (binding = 3) uniform sampler2D utextureh; + uniform ivec2 srcSize; + uniform ivec2 dstSize; + uniform ivec2 slr_a; + uniform ivec2 slr_max; + uniform vec2 slr_coeff; + uniform vec2 slr_coeff_tao; + out vec4 FragColor; + void main() + { + ivec2 tex_size = textureSize(utexture, 0); + vec2 eta = (gl_FragCoord.xy) * slr_coeff_tao - vec2(0.5); + ivec2 eta_c = ivec2(floor(eta.x), floor(eta.y)); + ivec2 coord_s = ivec2(eta_c.x - slr_a.x + 1, eta_c.y - slr_a.y + 1); + vec4 color = vec4(0, 0, 0, 0); + for (int i = 0; i < slr_max.y; i++) { + float w_i = texelFetch(utextureh, ivec2(i, gl_FragCoord.y), 0).r; + vec4 t = vec4(0, 0, 0, 0); + for (int j = 0; j < slr_max.x; j++) { + float w_j = texelFetch(utexturew, ivec2(j, gl_FragCoord.x), 0).r; + ivec2 coord = clamp(coord_s + ivec2(j, i), ivec2(0), tex_size - ivec2(1)); + t += w_j * texelFetch(utexture, coord, 0); } - FragColor = color; + color += t * w_i; } - )"; + FragColor = color; + } +)"; + +bool SLRShader::Build() +{ ImageTrace imageTrace("SLRShader::Build"); vShader_ = loadShader(GL_VERTEX_SHADER, vSlrShaderStr); fShader_ = loadShader(GL_FRAGMENT_SHADER, fSlrShaderStr); @@ -704,7 +696,6 @@ bool SLRShader::Use() glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, writeTexId_, 0); glClearColor(0, 1, 0, 0); glClear(GL_COLOR_BUFFER_BIT); - int texture_index = 0; if (eglImage_ != EGL_NO_IMAGE) { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, readTexId_); @@ -712,7 +703,6 @@ bool SLRShader::Use() glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, readTexId_); - texture_index = 1; } float coeff_w = ((float)targetSize_.width) / sourceSize_.width; float coeff_h = ((float)targetSize_.height) / sourceSize_.height; @@ -761,41 +751,41 @@ bool LapShader::Clear() return Shader::Clear(); } +static const char vLapShaderStr[] = + "#version 320 es\n" + "layout (location = 0) in vec3 position;\n" + "layout (location = 1) in vec2 texCoords;\n" + "out vec2 vTexCoords;\n" + "void main()\n" + "{\n" + " gl_Position = vec4(position.x, position.y, position.z, 1.0f);\n" + " vTexCoords = texCoords;\n" + "}\n"; + +static const char fLapShaderStr[] = R"(#version 320 es + precision mediump float; + in vec2 vTexCoords; + uniform sampler2D utexture; + uniform float alpha; + out vec4 FragColor; + void main() + { + vec2 screenSize = vec2(textureSize(utexture, 0)); + vec2 uv = gl_FragCoord.xy / screenSize.xy, ps = 1. / screenSize.xy; // pixel size + vec4 c = texture(utexture, uv); + vec4 top = texture(utexture, uv + vec2(0.0, ps.y)); + vec4 bottom = texture(utexture, uv - vec2(0.0, ps.y)); + vec4 left = texture(utexture, uv - vec2(ps.x, 0.0)); + vec4 right = texture(utexture, uv + vec2(ps.x, 0.0)); + FragColor = c + alpha* (4.0 * c - top - bottom - left - right); + } +)"; + bool LapShader::Build() { ImageTrace imageTrace("LapShader::Build"); - static const char vShaderStr[] = - "#version 320 es\n" - "layout (location = 0) in vec3 position;\n" - "layout (location = 1) in vec2 texCoords;\n" - "out vec2 vTexCoords;\n" - "void main()\n" - "{\n" - " gl_Position = vec4(position.x, position.y, position.z, 1.0f);\n" - " vTexCoords = texCoords;\n" - "}\n"; - - static const char fShaderStr[] = R"(#version 320 es - precision mediump float; - in vec2 vTexCoords; - uniform sampler2D utexture; - uniform float alpha; - out vec4 FragColor; - void main() - { - vec2 screenSize = vec2(textureSize(utexture, 0)); - vec2 uv = gl_FragCoord.xy / screenSize.xy, ps = 1. / screenSize.xy; // pixel size - vec4 c = texture(utexture, uv); - vec4 top = texture(utexture, uv + vec2(0.0, ps.y)); - vec4 bottom = texture(utexture, uv - vec2(0.0, ps.y)); - vec4 left = texture(utexture, uv - vec2(ps.x, 0.0)); - vec4 right = texture(utexture, uv + vec2(ps.x, 0.0)); - FragColor = c + alpha* (4.0 * c - top - bottom - left - right); - } - )"; - - vShader_ = loadShader(GL_VERTEX_SHADER, vShaderStr); - fShader_ = loadShader(GL_FRAGMENT_SHADER, fShaderStr); + vShader_ = loadShader(GL_VERTEX_SHADER, vLapShaderStr); + fShader_ = loadShader(GL_FRAGMENT_SHADER, fLapShaderStr); if (vShader_ == 0 || fShader_ == 0) { IMAGE_LOGE("slr_gpu LapShader LoadShader failed"); return false; diff --git a/frameworks/innerkitsimpl/egl_image/src/pixel_map_program_manager.cpp b/frameworks/innerkitsimpl/egl_image/src/pixel_map_program_manager.cpp index 19f5272d3770fb5b5668f78ba7a488b1a402a9f7..9fa6d77d65f58b5fb121707884aeb5e4cbfc90d4 100644 --- a/frameworks/innerkitsimpl/egl_image/src/pixel_map_program_manager.cpp +++ b/frameworks/innerkitsimpl/egl_image/src/pixel_map_program_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023 Huawei Device Co., Ltd. + * Copyright (C) 2025 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 @@ -21,7 +21,7 @@ namespace OHOS { namespace Media { -static const int MAX_GL_INSTANCE_NUM = 8; +static const int MAX_GL_INSTANCE_NUM = 4; constexpr int32_t MAX_CONTEXT_EXPIRED_TIME_SEC = 120; constexpr int32_t MIN_CONTEXT_EXPIRED_TIME_SEC = 10; static vector g_availInstances; @@ -141,7 +141,7 @@ void PixelMapProgramManager::DestroyOneInstance() if (instance != nullptr) delete instance; } int num = g_nowInstanceNum; - IMAGE_LOGE("slr_gpu %{public}s destroy opengl context(%{public}d)", __func__, num); + IMAGE_LOGI("slr_gpu %{public}s destroy opengl context(%{public}d)", __func__, num); } bool PixelMapProgramManager::BuildShader() diff --git a/frameworks/innerkitsimpl/test/fuzztest/imageinterfacepixelmap_fuzzer/src/image_interface_pixelmap_fuzzer.cpp b/frameworks/innerkitsimpl/test/fuzztest/imageinterfacepixelmap_fuzzer/src/image_interface_pixelmap_fuzzer.cpp index 0567131c74ca3683b372964e36125f0ad477a050..8cb62507cb9a51e099911abe9ac9aa0fb1eaae51 100644 --- a/frameworks/innerkitsimpl/test/fuzztest/imageinterfacepixelmap_fuzzer/src/image_interface_pixelmap_fuzzer.cpp +++ b/frameworks/innerkitsimpl/test/fuzztest/imageinterfacepixelmap_fuzzer/src/image_interface_pixelmap_fuzzer.cpp @@ -31,9 +31,6 @@ constexpr uint32_t MAX_LENGTH_MODULO = 1024; constexpr uint32_t PIXELFORMAT_MODULO = 8; constexpr uint32_t ALPHATYPE_MODULO = 4; constexpr uint32_t SCALEMODE_MODULO = 2; -constexpr uint32_t DMA_WIDTH = 1024; -constexpr uint32_t DMA_HEIGHT = 512; -constexpr uint32_t BOOLMODULE = 2; namespace OHOS { namespace Media { @@ -108,12 +105,6 @@ std::unique_ptr GetPixelMapFromOpts(const Media::Initialization return pixelmap; } -bool IsYuv(Media::PixelFormat format) -{ - return format == Media::PixelFormat::NV12 || format == Media::PixelFormat::NV21 || - format == Media::PixelFormat::YCBCR_P010 || format == Media::PixelFormat::YCRCB_P010; -} - void FuzzTestSetMemoryName() { Media::InitializationOptions opts = GetInitialRandomOpts(); @@ -272,17 +263,6 @@ void FuzzTestReadARGBPixels() } } -void FuzzTestAboutMap() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (opts.pixelFormat == PixelFormat::ALPHA_8 || !pixelmap) { - return; - } - pixelmap->UnMap(); - pixelmap->ReMap(); -} - static Rect GetRandomRect(int32_t width = 0, int32_t height = 0) { Rect rect; @@ -293,26 +273,6 @@ static Rect GetRandomRect(int32_t width = 0, int32_t height = 0) return rect; } -void FuzzTestReadWith5Args(bool isEditable) -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8) { - return; - } - opts.editable = isEditable; - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - Rect region = GetRandomRect(opts.size.width, opts.size.height); - int32_t srcSize = pixelmap->GetByteCount(); - uint32_t offset = GetData() % (srcSize >> 2); - uint32_t regionStride = pixelmap->GetPixelBytes() * region.width; - uint64_t dstSize = regionStride * region.height; - std::unique_ptr regionBuffer = std::make_unique(dstSize); - pixelmap->ReadPixels(dstSize, offset, regionStride, region, regionBuffer.get()); -} - void FuzzTestReadSinglePixel() { Media::InitializationOptions opts = GetInitialRandomOpts(); @@ -329,121 +289,6 @@ void FuzzTestReadSinglePixel() } } -void FuzzTestPureRandomSetAlpha() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8) { - return; - } - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - float percent = static_cast((GetData()) % 10) / 10.0; - if (SUCCESS != pixelmap->SetAlpha(percent)) { - return; - } -} - -void FuzzTestRGBA_F16PixelMapSetAlpha() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8) { - return; - } - opts.pixelFormat = PixelFormat::RGBA_F16; - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - float percent = static_cast((GetData()) % 10) / 10.0; - if (SUCCESS != pixelmap->SetAlpha(percent)) { - return; - } -} - -void FuzzTestRGBA_1010102PixelMapSetAlpha() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8) { - return; - } - opts.pixelFormat = PixelFormat::RGBA_1010102; - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - float percent = static_cast((GetData()) % 10) / 10.0; - if (SUCCESS != pixelmap->SetAlpha(percent)) { - return; - } -} - -void FuzzTestWritePixelsWith5Args(bool isEditable) -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8) { - return; - } - opts.editable = isEditable; - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - Rect region = GetRandomRect(opts.size.width, opts.size.height); - int32_t srcSize = pixelmap->GetByteCount(); - uint32_t offset = GetData() % (srcSize >> 2); - uint32_t regionStride = pixelmap->GetPixelBytes() * region.width; - uint64_t dstSize = regionStride * region.height; - std::unique_ptr regionBuffer_with_write = std::make_unique(dstSize); - pixelmap->WritePixels(regionBuffer_with_write.get(), dstSize, offset, regionStride, region); -} - -void FuzzTestCrop() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (opts.pixelFormat == PixelFormat::ALPHA_8 || opts.pixelFormat == PixelFormat::RGB_888) { - return; - } - opts.useDMA = GetData() % BOOLMODULE; - if (opts.useDMA) { - opts.size.height += DMA_HEIGHT; - opts.size.width += DMA_HEIGHT; - } - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - Rect rect = GetRandomRect(opts.size.width, opts.size.height); - pixelmap->crop(rect); -} - -void FuzzTestSetFunc() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - std::unique_ptr pixelmap = GetPixelMapFromOpts(opts); - if (!pixelmap) { - return; - } - pixelmap->SetFreePixelMapProc([](void *addr, void *context, uint32_t size) { - return; - }); -} - -void FuzzTestClone() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - if (IsYuv(opts.pixelFormat)) { - return; - } - std::unique_ptr pixelMap = GetPixelMapFromOpts(opts); - if (pixelMap != nullptr && pixelMap->IsAstc()) { - return; - } - int32_t errorCode = 0; - pixelMap->Clone(errorCode); -} - void CropCreate() { Media::InitializationOptions opts = GetInitialRandomOpts(); @@ -460,22 +305,9 @@ void CropCreate() PixelMap::Create(*(pixelmap.get()), rect, opts); } -void DmaAndYuvPixelMapCreate() -{ - Media::InitializationOptions opts = GetInitialRandomOpts(); - opts.size.height = DMA_HEIGHT; - opts.size.width = DMA_WIDTH; - opts.useDMA = true; - opts.pixelFormat = PixelFormat::YCBCR_P010; - std::unique_ptr pixelmap_dma_yuv = GetPixelMapFromOpts(opts); - opts.pixelFormat = PixelFormat::NV12; - std::unique_ptr pixelmap_dma_yuv_nv12 = GetPixelMapFromOpts(opts); -} - void CreatePixelMapFuzzTest() { CropCreate(); - DmaAndYuvPixelMapCreate(); } void PixelMapInterfaceFuzzTest() @@ -489,15 +321,6 @@ void PixelMapInterfaceFuzzTest() FuzzTestReadPixelsAndWritePixels(); FuzzTestReadARGBPixels(); FuzzTestReadSinglePixel(); - FuzzTestAboutMap(); - FuzzTestReadWith5Args(GetData() % 2); // 2: true or false - FuzzTestPureRandomSetAlpha(); - FuzzTestRGBA_F16PixelMapSetAlpha(); - FuzzTestRGBA_1010102PixelMapSetAlpha(); - FuzzTestWritePixelsWith5Args(GetData() % 2); // 2: true or false - FuzzTestCrop(); - FuzzTestSetFunc(); - FuzzTestClone(); } bool PixelMapMainFuzzTest(const uint8_t* data, size_t size) diff --git a/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/BUILD.gn b/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/BUILD.gn index 940c9c6ab8f6196a65109910f4aa179ae37874a5..0693dc82b0e034cdb9cb00b8ad5415f793be9fa6 100644 --- a/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/BUILD.gn +++ b/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/BUILD.gn @@ -29,6 +29,9 @@ ohos_fuzztest("ImagePixelmapBaseFuzzTest") { "c_utils:utils", "hilog:libhilog", ] + cflags = [ + "-Dprotected=public", + ] fuzz_config_file = "$image_subsystem/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer" module_out_path = "multimedia_image/image_framework" } diff --git a/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/src/image_pixelmap_fuzzer.cpp b/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/src/image_pixelmap_fuzzer.cpp index d78b287ccaeac32ea49c0ccc2f204061c3af7bd0..a1eaa0cf73ee11e08716ad47ffbb468dc4fc228c 100644 --- a/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/src/image_pixelmap_fuzzer.cpp +++ b/frameworks/innerkitsimpl/test/fuzztest/imagepixelmapBase_fuzzer/src/image_pixelmap_fuzzer.cpp @@ -15,15 +15,17 @@ #include "image_pixelmap_fuzzer.h" +#include #include #include -#include - -#include "pixel_map.h" - -#include #include + #include "image_log.h" +#include "image_utils.h" +#include "media_errors.h" +#include "message_parcel.h" +#include "pixel_map.h" +#include "securec.h" constexpr uint32_t WIDTH_FACTOR = 4; constexpr uint32_t STRING_LENGTH = 10; @@ -82,7 +84,7 @@ std::string GetStringFromData() /* * get parcel from g_data */ -bool ChangeParcel(Parcel &parcel) +bool ChangeParcel(MessageParcel &parcel) { if (!parcel.WriteBuffer(g_data, g_size)) { return false; @@ -135,7 +137,7 @@ std::unique_ptr GetPixelMapFromData(Media::PixelFormat pixelFor opts.useSourceIfMatch = GetData(); size_t datalength = width * height * WIDTH_FACTOR; uint32_t* colorData = new uint32_t[datalength]; - for (size_t i = 0; i < width * height; i++) { + for (int32_t i = 0; i < width * height; i++) { colorData[i] = GetData(); } auto pixelmap = Media::PixelMap::Create(colorData, datalength, opts); @@ -150,20 +152,57 @@ std::unique_ptr GetPixelMapFromData(Media::PixelFormat pixelFor * get a pixelmap from other Pixelmap */ std::unique_ptr GetPixelMapFromPixelmap(std::unique_ptr &pixelMap, - Media::PixelFormat pixelFormat = PixelFormat::UNKNOWN) + Media::PixelFormat pixelFormat = PixelFormat::UNKNOWN, + bool crop = false) { int32_t width = pixelMap->GetWidth() / DIVISOR + NUM_1; int32_t height = pixelMap->GetHeight() / DIVISOR + NUM_1; + Rect rect; + if (crop) { + rect.width = width / 2; // crop half of the width + rect.height = height / 2; // crop half of the height + } Media::InitializationOptions opts; opts.size.width = width; opts.size.height = height; - auto outPixelmap = Media::PixelMap::Create(*pixelMap, opts); + auto outPixelmap = Media::PixelMap::Create(*pixelMap, rect, opts); if (outPixelmap == nullptr) { return nullptr; } return outPixelmap; } +/* + * Construct a HEAP allocated PixelMap + */ +std::unique_ptr ConstructHeapPixelMap(PixelFormat format) +{ + std::unique_ptr pixelMap = std::make_unique(); + Media::ImageInfo info; + info.width = GetData() % MAX_LENGTH_MODULO; + info.height = GetData() % MAX_LENGTH_MODULO; + info.pixelFormat = format; + pixelMap->SetImageInfo(info); + + int32_t rowDataSize = ImageUtils::GetRowDataSizeByPixelFormat(info.size.width, info.pixelFormat); + if (rowDataSize <= 0) { + return nullptr; + } + size_t bufferSize = rowDataSize * info.size.height; + void* buffer = malloc(bufferSize); // Buffer's lifecycle will be held by pixelMap + if (!buffer) { + return nullptr; + } + char* ch = static_cast(buffer); + for (unsigned int i = 0; i < bufferSize; i++) { + *(ch++) = static_cast(i); + } + + pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr); + + return pixelMap; +} + /* * get yuv info */ @@ -368,9 +407,6 @@ bool PixelMapSetImagePropertiesTest(std::unique_ptr &pixelMap) size.height = GetData(); Media::PixelFormat pixelFormat = static_cast(GetData()); pixelMap->ResetConfig(size, pixelFormat); - // Set Alpha Type - Media::AlphaType alphaType = static_cast(GetData()); - pixelMap->SetAlphaType(alphaType); // Set Memory Name std::string memoryName = GetStringFromData(); pixelMap->SetMemoryName(memoryName); @@ -409,15 +445,21 @@ bool PixelMapSetImagePropertiesTest(std::unique_ptr &pixelMap) } /* - * test pixelmap is same image + * test pixelmap convert alpha format */ -bool PixelMapIsSameImageTest(std::unique_ptr &pixelMap) +bool PixelMapConvertAlphaFormatTest(std::unique_ptr &rPixelMap) { - std::unique_ptr otherPixelMap = GetPixelMapFromOpts(); - if (!otherPixelMap) { + std::unique_ptr wPixelMap = GetPixelMapFromOpts(); + if (!wPixelMap) { return false; } - pixelMap->IsSameImage(*(otherPixelMap.get())); + if (!rPixelMap->IsSameImage(*wPixelMap)) { + bool isPremul = GetData(); + uint32_t res = rPixelMap->ConvertAlphaFormat(*wPixelMap, isPremul); + if (res != SUCCESS) { + return false; + } + } return true; } @@ -550,7 +592,7 @@ bool PixelMapCSTest(std::unique_ptr &pixelMap) bool PixelMapIPCTest(std::unique_ptr &pixelMap) { // test parcel pixelmap - Parcel parcel; + MessageParcel parcel; pixelMap->SetMemoryName("MarshallingPixelMap"); if (!pixelMap->Marshalling(parcel)) { IMAGE_LOGI("PixelMapIPCTest Marshalling failed id: %{public}d, isUnmap: %{public}d", @@ -630,6 +672,13 @@ bool PixelMapMainFuzzTest(const uint8_t* data, size_t size) return false; } + // create cropped PixelMap from other PixelMap + std::unique_ptr pixelMapCropFromOtherPixelMap = GetPixelMapFromPixelmap(pixelMapFromOpts_rgba8888, + Media::PixelFormat::RGBA_8888, true); + if (!pixelMapCropFromOtherPixelMap) { + return false; + } + return true; } @@ -655,6 +704,18 @@ bool PixelMapFromDataMainFuzzTest() if (!pixelMapFromData) { return false; } + if (!pixelMapFromData->CloseFd()) { + return false; + } + + // create HEAP allocated + std::unique_ptr pixelMapHeap = ConstructHeapPixelMap(Media::PixelFormat::RGBA_8888); + if (!pixelMapHeap) { + return false; + } + if (!pixelMapHeap->CloseFd()) { + return false; + } return true; }