diff options
author | 2016-12-12 16:14:11 -0800 | |
---|---|---|
committer | 2016-12-13 12:59:12 -0800 | |
commit | 9c97e48fbe389180b4b64845f093c53c92c374f3 (patch) | |
tree | 79622cba9a9867b3cea60f690f50a4eaa3a95cc0 | |
parent | 61341618c5555fc5925879c4a0a797eabf92c3c9 (diff) |
HWUI: set correct sampler for external texture in shaders
Test: hwuimacro hwbitmapcompositeshader
bug:30999911
Change-Id: Ic63f7109a4a7069b62c0b21efae2d4ba7e6d64be
-rw-r--r-- | libs/hwui/Program.h | 6 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 1 | ||||
-rw-r--r-- | libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp | 91 |
4 files changed, 107 insertions, 2 deletions
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 9c4cb098b4c3..e70982f5444a 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -54,6 +54,7 @@ namespace uirenderer { #define PROGRAM_KEY_COLOR_MATRIX 0x20 #define PROGRAM_KEY_COLOR_BLEND 0x40 #define PROGRAM_KEY_BITMAP_NPOT 0x80 +#define PROGRAM_KEY_BITMAP_EXTERNAL 0x100 #define PROGRAM_KEY_SWAP_SRC_DST 0x2000 @@ -133,6 +134,7 @@ struct ProgramDescription { // Shaders bool hasBitmap; + bool isShaderBitmapExternal; bool useShaderBasedWrap; bool hasVertexAlpha; @@ -180,6 +182,7 @@ struct ProgramDescription { modulate = false; hasBitmap = false; + isShaderBitmapExternal = false; useShaderBasedWrap = false; hasGradient = false; @@ -239,6 +242,9 @@ struct ProgramDescription { key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT; key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT; } + if (isShaderBitmapExternal) { + key |= PROGRAM_KEY_BITMAP_EXTERNAL; + } } if (hasGradient) key |= PROGRAM_KEY_GRADIENT; key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT; diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 0c2309faf4ea..a3819f76296d 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -145,6 +145,8 @@ const char* gFS_Uniforms_GradientSampler[2] = { }; const char* gFS_Uniforms_BitmapSampler = "uniform sampler2D bitmapSampler;\n"; +const char* gFS_Uniforms_BitmapExternalSampler = + "uniform samplerExternalOES bitmapSampler;\n"; const char* gFS_Uniforms_ColorOp[3] = { // None "", @@ -576,7 +578,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (blendFramebuffer) { shader.append(gFS_Header_Extension_FramebufferFetch); } - if (description.hasExternalTexture) { + if (description.hasExternalTexture + || (description.hasBitmap && description.isShaderBitmapExternal)) { shader.append(gFS_Header_Extension_ExternalTexture); } @@ -693,7 +696,11 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti } if (description.hasBitmap) { - shader.append(gFS_Uniforms_BitmapSampler); + if (description.isShaderBitmapExternal) { + shader.append(gFS_Uniforms_BitmapExternalSampler); + } else { + shader.append(gFS_Uniforms_BitmapSampler); + } } shader.append(gFS_Uniforms_ColorOp[static_cast<int>(description.colorOp)]); diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index 34e6a06c3dc2..a9de8695b558 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -218,6 +218,7 @@ bool tryStoreBitmap(Caches& caches, const SkShader& shader, const Matrix4& model const float height = outData->bitmapTexture->height(); description->hasBitmap = true; + description->isShaderBitmapExternal = hwuiBitmap->isHardware(); // gralloc doesn't support non-clamp modes if (hwuiBitmap->isHardware() || (!caches.extensions().hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp new file mode 100644 index 000000000000..83b01e906427 --- /dev/null +++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016 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 "TestSceneBase.h" +#include "utils/Color.h" + +#include <gui/IGraphicBufferAlloc.h> +#include <gui/ISurfaceComposer.h> +#include <private/gui/ComposerService.h> +#include <binder/IServiceManager.h> +#include <ui/PixelFormat.h> +#include <SkGradientShader.h> +#include <SkImagePriv.h> + +class HwBitmapInCompositeShader; + +static TestScene::Registrar _HwBitmapInCompositeShader(TestScene::Info{ + "hwbitmapcompositeshader", + "Draws composite shader with hardware bitmap", + TestScene::simpleCreateScene<HwBitmapInCompositeShader> +}); + +class HwBitmapInCompositeShader : public TestScene { +public: + sp<RenderNode> card; + void createContent(int width, int height, Canvas& canvas) override { + canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver); + + status_t error; + sp<ISurfaceComposer> composer(ComposerService::getComposerService()); + sp<IGraphicBufferAlloc> alloc(composer->createGraphicBufferAlloc()); + uint32_t usage = GraphicBuffer::USAGE_HW_TEXTURE + | GraphicBuffer::USAGE_SW_READ_NEVER + | GRALLOC_USAGE_SW_WRITE_RARELY; + sp<GraphicBuffer> buffer = alloc->createGraphicBuffer(400, 200, PIXEL_FORMAT_RGBA_8888, 1, + usage, &error); + + unsigned char* pixels = nullptr; + buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, ((void**)&pixels)); + size_t size = bytesPerPixel(buffer->getPixelFormat()) * buffer->getStride() + * buffer->getHeight(); + memset(pixels, 0, size); + for (int i = 0; i < 6000; i++) { + pixels[4000 + 4 * i + 0] = 255; + pixels[4000 + 4 * i + 1] = 255; + pixels[4000 + 4 * i + 2] = 0; + pixels[4000 + 4 * i + 3] = 255; + } + buffer->unlock(); + sk_sp<Bitmap> hardwareBitmap(Bitmap::createFrom(buffer)); + sk_sp<SkShader> hardwareShader(createBitmapShader(*hardwareBitmap)); + + SkPoint center; + center.set(50, 50); + SkColor colors[2]; + colors[0] = Color::Black; + colors[1] = Color::White; + sk_sp<SkShader> gradientShader = SkGradientShader::MakeRadial(center, 50, colors, nullptr, + 2, SkShader::TileMode::kRepeat_TileMode); + + sk_sp<SkShader> compositeShader( + SkShader::MakeComposeShader(hardwareShader, gradientShader, SkBlendMode::kDstATop)); + + SkPaint paint; + paint.setShader(std::move(compositeShader)); + canvas.drawRoundRect(0, 0, 400, 200, 10.0f, 10.0f, paint); + } + + void doFrame(int frameNr) override { } + + sk_sp<SkShader> createBitmapShader(Bitmap& bitmap) { + SkBitmap skBitmap; + bitmap.getSkBitmapForShaders(&skBitmap); + sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(skBitmap, kNever_SkCopyPixelsMode); + return image->makeShader(SkShader::TileMode::kClamp_TileMode, + SkShader::TileMode::kClamp_TileMode); + } +};
\ No newline at end of file |