Loading libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,7 @@ cc_test { srcs: [ "tests/unit/main.cpp", "tests/unit/ABitmapTests.cpp", "tests/unit/AutoBackendTextureReleaseTests.cpp", "tests/unit/CacheManagerTests.cpp", "tests/unit/CanvasContextTests.cpp", "tests/unit/CanvasOpTests.cpp", Loading libs/hwui/AutoBackendTextureRelease.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -32,9 +32,17 @@ AutoBackendTextureRelease::AutoBackendTextureRelease(GrDirectContext* context, bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT); GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(context, buffer, desc.format, false); LOG_ALWAYS_FATAL_IF(!backendFormat.isValid(), __FILE__ " Invalid GrBackendFormat. GrBackendApi==%" PRIu32 ", AHardwareBuffer_Format==%" PRIu32 ".", static_cast<int>(context->backend()), desc.format); mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture( context, buffer, desc.width, desc.height, &mDeleteProc, &mUpdateProc, &mImageCtx, createProtectedImage, backendFormat, false); LOG_ALWAYS_FATAL_IF(!mBackendTexture.isValid(), __FILE__ " Invalid GrBackendTexture. Width==%" PRIu32 ", height==%" PRIu32 ", protected==%d", desc.width, desc.height, createProtectedImage); } void AutoBackendTextureRelease::unref(bool releaseImage) { Loading Loading @@ -74,13 +82,13 @@ void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer, AHardwareBuffer_Desc desc; AHardwareBuffer_describe(buffer, &desc); SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format); // The following ref will be counteracted by Skia calling releaseProc, either during // MakeFromTexture if there is a failure, or later when SkImage is discarded. It must // be called before MakeFromTexture, otherwise Skia may remove HWUI's ref on failure. ref(); mImage = SkImage::MakeFromTexture( context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace), releaseProc, this); if (mImage.get()) { // The following ref will be counteracted by releaseProc, when SkImage is discarded. ref(); } } void AutoBackendTextureRelease::newBufferContent(GrDirectContext* context) { Loading libs/hwui/AutoBackendTextureRelease.h +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ namespace android { namespace uirenderer { // Friend TestUtils serves as a proxy for any test cases that require access to private members. class TestUtils; /** * AutoBackendTextureRelease manages EglImage/VkImage lifetime. It is a ref-counted object * that keeps GPU resources alive until the last SkImage object using them is destroyed. Loading Loading @@ -66,6 +69,9 @@ private: // mImage is the SkImage created from mBackendTexture. sk_sp<SkImage> mImage; // Friend TestUtils serves as a proxy for any test cases that require access to private members. friend class TestUtils; }; } /* namespace uirenderer */ Loading libs/hwui/tests/common/TestUtils.h +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <AutoBackendTextureRelease.h> #include <DisplayList.h> #include <Matrix.h> #include <Properties.h> Loading Loading @@ -283,6 +284,11 @@ public: static SkRect getClipBounds(const SkCanvas* canvas); static SkRect getLocalClipBounds(const SkCanvas* canvas); static int getUsageCount(const AutoBackendTextureRelease* textureRelease) { EXPECT_NE(nullptr, textureRelease); return textureRelease->mUsageCount; } struct CallCounts { int sync = 0; int contextDestroyed = 0; Loading libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * 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 <gtest/gtest.h> #include "AutoBackendTextureRelease.h" #include "tests/common/TestUtils.h" using namespace android; using namespace android::uirenderer; AHardwareBuffer* allocHardwareBuffer() { AHardwareBuffer* buffer; AHardwareBuffer_Desc desc = { .width = 16, .height = 16, .layers = 1, .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, }; constexpr int kSucceeded = 0; int status = AHardwareBuffer_allocate(&desc, &buffer); EXPECT_EQ(kSucceeded, status); return buffer; } // Expands to AutoBackendTextureRelease_makeImage_invalid_RenderThreadTest, // set as friend in AutoBackendTextureRelease.h RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_invalid) { AHardwareBuffer* buffer = allocHardwareBuffer(); AutoBackendTextureRelease* textureRelease = new AutoBackendTextureRelease(renderThread.getGrContext(), buffer); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); // SkImage::MakeFromTexture should fail if given null GrDirectContext. textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, /*context = */ nullptr); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); textureRelease->unref(true); AHardwareBuffer_release(buffer); } // Expands to AutoBackendTextureRelease_makeImage_valid_RenderThreadTest, // set as friend in AutoBackendTextureRelease.h RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_valid) { AHardwareBuffer* buffer = allocHardwareBuffer(); AutoBackendTextureRelease* textureRelease = new AutoBackendTextureRelease(renderThread.getGrContext(), buffer); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, renderThread.getGrContext()); EXPECT_EQ(2, TestUtils::getUsageCount(textureRelease)); textureRelease->unref(true); AHardwareBuffer_release(buffer); } Loading
libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -674,6 +674,7 @@ cc_test { srcs: [ "tests/unit/main.cpp", "tests/unit/ABitmapTests.cpp", "tests/unit/AutoBackendTextureReleaseTests.cpp", "tests/unit/CacheManagerTests.cpp", "tests/unit/CanvasContextTests.cpp", "tests/unit/CanvasOpTests.cpp", Loading
libs/hwui/AutoBackendTextureRelease.cpp +12 −4 Original line number Diff line number Diff line Loading @@ -32,9 +32,17 @@ AutoBackendTextureRelease::AutoBackendTextureRelease(GrDirectContext* context, bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT); GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(context, buffer, desc.format, false); LOG_ALWAYS_FATAL_IF(!backendFormat.isValid(), __FILE__ " Invalid GrBackendFormat. GrBackendApi==%" PRIu32 ", AHardwareBuffer_Format==%" PRIu32 ".", static_cast<int>(context->backend()), desc.format); mBackendTexture = GrAHardwareBufferUtils::MakeBackendTexture( context, buffer, desc.width, desc.height, &mDeleteProc, &mUpdateProc, &mImageCtx, createProtectedImage, backendFormat, false); LOG_ALWAYS_FATAL_IF(!mBackendTexture.isValid(), __FILE__ " Invalid GrBackendTexture. Width==%" PRIu32 ", height==%" PRIu32 ", protected==%d", desc.width, desc.height, createProtectedImage); } void AutoBackendTextureRelease::unref(bool releaseImage) { Loading Loading @@ -74,13 +82,13 @@ void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer, AHardwareBuffer_Desc desc; AHardwareBuffer_describe(buffer, &desc); SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format); // The following ref will be counteracted by Skia calling releaseProc, either during // MakeFromTexture if there is a failure, or later when SkImage is discarded. It must // be called before MakeFromTexture, otherwise Skia may remove HWUI's ref on failure. ref(); mImage = SkImage::MakeFromTexture( context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace), releaseProc, this); if (mImage.get()) { // The following ref will be counteracted by releaseProc, when SkImage is discarded. ref(); } } void AutoBackendTextureRelease::newBufferContent(GrDirectContext* context) { Loading
libs/hwui/AutoBackendTextureRelease.h +6 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,9 @@ namespace android { namespace uirenderer { // Friend TestUtils serves as a proxy for any test cases that require access to private members. class TestUtils; /** * AutoBackendTextureRelease manages EglImage/VkImage lifetime. It is a ref-counted object * that keeps GPU resources alive until the last SkImage object using them is destroyed. Loading Loading @@ -66,6 +69,9 @@ private: // mImage is the SkImage created from mBackendTexture. sk_sp<SkImage> mImage; // Friend TestUtils serves as a proxy for any test cases that require access to private members. friend class TestUtils; }; } /* namespace uirenderer */ Loading
libs/hwui/tests/common/TestUtils.h +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <AutoBackendTextureRelease.h> #include <DisplayList.h> #include <Matrix.h> #include <Properties.h> Loading Loading @@ -283,6 +284,11 @@ public: static SkRect getClipBounds(const SkCanvas* canvas); static SkRect getLocalClipBounds(const SkCanvas* canvas); static int getUsageCount(const AutoBackendTextureRelease* textureRelease) { EXPECT_NE(nullptr, textureRelease); return textureRelease->mUsageCount; } struct CallCounts { int sync = 0; int contextDestroyed = 0; Loading
libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * 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 <gtest/gtest.h> #include "AutoBackendTextureRelease.h" #include "tests/common/TestUtils.h" using namespace android; using namespace android::uirenderer; AHardwareBuffer* allocHardwareBuffer() { AHardwareBuffer* buffer; AHardwareBuffer_Desc desc = { .width = 16, .height = 16, .layers = 1, .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY | AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY, }; constexpr int kSucceeded = 0; int status = AHardwareBuffer_allocate(&desc, &buffer); EXPECT_EQ(kSucceeded, status); return buffer; } // Expands to AutoBackendTextureRelease_makeImage_invalid_RenderThreadTest, // set as friend in AutoBackendTextureRelease.h RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_invalid) { AHardwareBuffer* buffer = allocHardwareBuffer(); AutoBackendTextureRelease* textureRelease = new AutoBackendTextureRelease(renderThread.getGrContext(), buffer); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); // SkImage::MakeFromTexture should fail if given null GrDirectContext. textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, /*context = */ nullptr); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); textureRelease->unref(true); AHardwareBuffer_release(buffer); } // Expands to AutoBackendTextureRelease_makeImage_valid_RenderThreadTest, // set as friend in AutoBackendTextureRelease.h RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_valid) { AHardwareBuffer* buffer = allocHardwareBuffer(); AutoBackendTextureRelease* textureRelease = new AutoBackendTextureRelease(renderThread.getGrContext(), buffer); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, renderThread.getGrContext()); EXPECT_EQ(2, TestUtils::getUsageCount(textureRelease)); textureRelease->unref(true); AHardwareBuffer_release(buffer); }