From 4adc54b9973e7d2d2f22b83e32abbbeb545b8b4e Mon Sep 17 00:00:00 2001 From: Daniel Hillenbrand Date: Fri, 14 Jun 2013 23:16:18 +0200 Subject: skia: exynos4: add support for fimg2d3x Change-Id: Ie0509e7d537fe2a73b23c30f5128d80ee48c1d7d --- src/core/SkBlitter_ARGB32.cpp | 6 +- src/core/SkDraw.cpp | 17 ++- src/core/SkFimgApi3x.cpp | 345 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 src/core/SkFimgApi3x.cpp (limited to 'src') diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index 44d0d8c..eb1e622 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -18,7 +18,11 @@ #if defined(FIMG2D_ENABLED) #include "SkBitmap.h" #include "SkBitmapProcShader.h" +#if defined(FIMG2D3X) +#include "SkFimgApi3x.h" +#elif defined(FIMG2D4X) #include "SkFimgApi4x.h" +#endif extern Fimg fimg; extern SkMutex gG2DMutex; #endif @@ -224,7 +228,7 @@ void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) { uint32_t color = fPMColor; size_t rowBytes = fDevice.rowBytes(); -#if defined(FIMG2D_ENABLED) +#if defined(FIMG2D_ENABLED) && defined (FIMG2D4X) gG2DMutex.acquire(); int retFimg = FimgARGB32_Rect(fimg, fDevice.getAddr32(0, 0), x, y, width, height, rowBytes, color); diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 4460eb8..e3ee31c 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -34,7 +34,11 @@ #include #if defined(FIMG2D_ENABLED) +#if defined(FIMG2D3X) +#include "SkFimgApi3x.h" +#elif defined(FIMG2D4X) #include "SkFimgApi4x.h" +#endif Fimg fimg; SkMutex gG2DMutex; #endif @@ -1261,7 +1265,10 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, fimg.clipL = cr.fLeft; fimg.clipR = cr.fRight; +#if defined(FIMG2D4X) fimg.mskAddr = NULL; +#endif + fimg.rotate = 0; SkXfermode::Mode mode; @@ -1272,8 +1279,13 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, fimg.colorFilter = (int)paint.getColorFilter(); fimg.alpha = paint.getAlpha(); - if (bitmap.isOpaque() && (255 == fimg.alpha)) + if (bitmap.isOpaque() && (255 == fimg.alpha)) { +#if defined(FIMG2D3X) + fimg.alpha = 256; +#elif defined(FIMG2D4X) fimg.alpha = 255; +#endif + } if (fimg.srcAddr != NULL) { int retFimg = FimgApiStretch(&fimg, __func__); @@ -1343,7 +1355,10 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, fimg.dstColorFormat = fBitmap->config(); fimg.dstAddr = (unsigned char *)fBitmap->getAddr(0,0); +#if defined(FIMG2D4X) fimg.mskAddr = NULL; +#endif + fimg.rotate = 0; fimg.alpha = paint.getAlpha(); diff --git a/src/core/SkFimgApi3x.cpp b/src/core/SkFimgApi3x.cpp new file mode 100644 index 0000000..5795371 --- /dev/null +++ b/src/core/SkFimgApi3x.cpp @@ -0,0 +1,345 @@ +/* +** +** Copyright 2009 Samsung Electronics 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. +** +*/ + +#if defined(FIMG2D_ENABLED) + +#include "SkFimgApi3x.h" + +#define G2D_BLOCKING_USE 0 + +// 0 kRGB_565_Config +// 1 kARGB_4444_Config +// 2 kARGB_8888_Config +// [dst][src][option] + +#if FIMGAPI_DMC_SIMD_OPT_USE +#if FIMGAPI_HYBRID_USE +int comp_value[3][3][4] = { + {{360*600, 78*130, 168*280, 66*110}, {78*130, 54*90, 80*140, 66*110}, {168*280, 162*270, 102*170, 72*120}}, + {{54*90, 42*70, 54*90, 42*70}, {54*90, 48*80, 54*90, 48*80}, {66*110, 54*90, 66*110, 54*90}}, + {{84*140, 54*90, 84*130, 54*90}, {102*170, 78*130, 96*160, 78*130}, {120*200, 66*110, 96*160, 72*120}} +}; +#else +int comp_value[3][3][4] = { + {{480*800, 78*130, 168*280, 66*110}, {78*130, 54*90, 80*140, 66*110}, {204*340, 216*360, 102*170, 72*120}}, + {{54*90, 42*70, 54*90, 42*70}, {54*90, 48*80, 54*90, 48*80}, {66*110, 54*90, 66*110, 54*90}}, + {{84*140, 54*90, 84*130, 54*90}, {102*170, 78*130, 96*160, 78*130}, {180*300, 66*110, 96*160, 72*120}} +}; +#endif +#else +#if FIMGAPI_HYBRID_USE +int comp_value[3][3][4] = { + {{360*600, 78*130, 168*280, 66*110}, {78*130, 54*90, 80*140, 66*110}, {168*280, 162*270, 102*170, 72*120}}, + {{54*90, 42*70, 54*90, 42*70}, {54*90, 48*80, 54*90, 48*80}, {66*110, 54*90, 66*110, 54*90}}, + {{84*140, 54*90, 84*130, 54*90}, {102*170, 78*130, 96*160, 78*130}, {120*200, 66*110, 96*160, 72*120}} +}; +#else +int comp_value[3][3][4] = { + {{480*800, 78*130, 168*280, 66*110}, {78*130, 54*90, 80*140, 66*110}, {204*340, 216*360, 102*170, 72*120}}, + {{54*90, 42*70, 54*90, 42*70}, {54*90, 48*80, 54*90, 48*80}, {66*110, 54*90, 66*110, 54*90}}, + {{84*140, 54*90, 84*130, 54*90}, {102*170, 78*130, 96*160, 78*130}, {180*300, 66*110, 96*160, 72*120}} +}; +#endif +#endif + +int FimgApiCheckPossibleHybrid(Fimg *fimg) +{ + if (!((fimg->srcW == fimg->dstW) && (fimg->srcH == fimg->dstH))) + return 0; + if (!((fimg->clipB - fimg->clipT) >= 40)) + return 0; + + if (fimg->canusehybrid == 0) + return 0; + + if (fimg->srcColorFormat == SkBitmap::kARGB_8888_Config) { + if (fimg->dstColorFormat == SkBitmap::kARGB_8888_Config) { + if (fimg->alpha < G2D_ALPHA_VALUE_MAX) + return 9; + else + return 7; + } else if (fimg->dstColorFormat == SkBitmap::kRGB_565_Config) { + if (fimg->alpha < G2D_ALPHA_VALUE_MAX) + return 7; + else + return 7; + } + } else if (fimg->srcColorFormat == SkBitmap::kRGB_565_Config) { + if (fimg->dstColorFormat == SkBitmap::kRGB_565_Config) { + if (fimg->alpha < G2D_ALPHA_VALUE_MAX) + return 9; + else + return 5; + } + } + return 0; +} + +bool FimgApiCheckPossible(Fimg *fimg) +{ + switch (fimg->srcColorFormat) { + case SkBitmap::kRGB_565_Config: + case SkBitmap::kARGB_8888_Config: + case SkBitmap::kARGB_4444_Config: + break; + default: + return false; + break; + } + + switch (fimg->dstColorFormat) { + case SkBitmap::kRGB_565_Config: +#if FIMGAPI_DITHERMODE_USE_SW + if ((fimg->srcColorFormat == SkBitmap::kARGB_8888_Config) && + (fimg->isDither == true)) + return false; + else + break; +#endif + case SkBitmap::kARGB_8888_Config: + break; + case SkBitmap::kARGB_4444_Config: +#if FIMGAPI_DITHERMODE_USE_SW + if ((fimg->srcColorFormat == SkBitmap::kARGB_8888_Config) && + (fimg->isDither == true)) + return false; +#endif + break; + default: + return false; + } + + switch (fimg->xfermode) { + case SkXfermode::kSrcOver_Mode: + break; + case SkXfermode::kClear_Mode: + break; + case SkXfermode::kSrc_Mode: + if (fimg->alpha < G2D_ALPHA_VALUE_MAX) + return false; + break; + default: + return false; + } + +#if FIMGAPI_FILTERMODE_USE_SW + if ((fimg->srcW != fimg->dstW) || (fimg->srcH != fimg->dstH)) + if (fimg->isFilter == true) + return false; +#endif + + if (fimg->colorFilter != NULL) + return false; + + if ((fimg->srcAddr == NULL) || (fimg->dstAddr == NULL)) + return false; + + if (fimg->matrixType & SkMatrix::kAffine_Mask) + return false; + + if ((fimg->matrixSx < 0) || (fimg->matrixSy < 0)) + return false; + + if ((fimg->srcX + fimg->srcW) > 8000 || (fimg->srcY + fimg->srcH) > 8000) + return false; + + if ((fimg->dstX + fimg->dstW) > 8000 || (fimg->dstY + fimg->dstH) > 8000) + return false; + + if ((fimg->clipT < 0) || (fimg->clipB < 0) || (fimg->clipL < 0) || (fimg->clipR < 0)) { + SkDebugf("Invalid clip value: TBLR = (%d, %d, %d, %d)",fimg->clipT, fimg->clipB, fimg->clipL, fimg->clipR); + return false; + } + + if ((fimg->clipT >= fimg->clipB) || (fimg->clipL >= fimg->clipR)) { + SkDebugf("Invalid clip value: TBLR = (%d, %d, %d, %d)",fimg->clipT, fimg->clipB, fimg->clipL, fimg->clipR); + return false; + } + + return true; +} + +bool FimgApiCheckPossible_Clipping(Fimg *fimg) +{ + if (((fimg->clipR - fimg->clipL) <= 0) || ((fimg->clipB - fimg->clipT) <= 0)) + return false; + return true; +} + +bool FimgApiCompromise(Fimg *fimg) +{ + int comp_opt = 0; + if ((fimg->srcW != fimg->dstW) || (fimg->srcH != fimg->dstH)) { + if ((fimg->alpha != 256) && (fimg->alpha != 255)) + comp_opt = COPT_AS; + else + comp_opt = COPT_NAS; + } else { + if ((fimg->alpha != 256) && (fimg->alpha != 255)) + comp_opt = COPT_ANS; + else + comp_opt = COPT_NANS; + } + + if ((fimg->isFilter == true) && ((comp_opt == COPT_AS) || (comp_opt == COPT_NAS))) + if (((fimg->clipR - fimg->clipL) * (fimg->clipB - fimg->clipT)) >= COMP_VALUE_FILTER_SCALE) + return true; + + if ((((fimg->clipR - fimg->clipL)*1.2) * ((fimg->clipB - fimg->clipT)*0.8)) < comp_value[fimg->dstColorFormat -4][fimg->srcColorFormat - 4][comp_opt]) + return false; + + return true; +} + +int FimgApiStretch(Fimg *fimg, const char *func_name) +{ + int ret; + + if (FimgApiCheckPossible(fimg) == false) + return false; + + if (fimg->clipL < fimg->dstX) + fimg->clipL = fimg->dstX; + if (fimg->clipT < fimg->dstY) + fimg->clipT = fimg->dstY; + if (fimg->clipR > (fimg->dstX + fimg->dstW)) + fimg->clipR = fimg->dstX + fimg->dstW; + if (fimg->clipB > (fimg->dstY + fimg->dstH)) + fimg->clipB = fimg->dstY + fimg->dstH; + +#if FIMGAPI_COMPROMISE_USE + if (FimgApiCompromise(fimg) == false) + return false; +#endif + + int srcColorFormat = FimgApi::COLOR_FORMAT_BASE; + int dstColorFormat = FimgApi::COLOR_FORMAT_BASE; + int rotate = FimgApi::ROTATE_0; + int alpha = fimg->alpha; + + switch (fimg->srcColorFormat) { + case SkBitmap::kRGB_565_Config: + srcColorFormat = FimgApi::COLOR_FORMAT_RGB_565; + break; + case SkBitmap::kARGB_4444_Config: + srcColorFormat = FimgApi::COLOR_FORMAT_RGBA_4444; + break; + case SkBitmap::kARGB_8888_Config: + srcColorFormat = FimgApi::COLOR_FORMAT_ABGR_8888; + break; + default: + return false; + } + + switch (fimg->dstColorFormat) { + case SkBitmap::kRGB_565_Config: + dstColorFormat = FimgApi::COLOR_FORMAT_RGB_565; + break; + case SkBitmap::kARGB_4444_Config: + dstColorFormat = FimgApi::COLOR_FORMAT_RGBA_4444; + break; + case SkBitmap::kARGB_8888_Config: + dstColorFormat = FimgApi::COLOR_FORMAT_ABGR_8888; + break; + default: + return false; + } + + switch (fimg->rotate) { + case 0: + rotate = FimgApi::ROTATE_0; + break; + case 90: + rotate = FimgApi::ROTATE_90; + break; + case 180: + rotate = FimgApi::ROTATE_180; + break; + case 270: + rotate = FimgApi::ROTATE_270; + break; + default: + #ifdef DEBUG_ON_FIMGAPISTRETCH_LEVEL + SkDebugf("%s::unsuppoted angle(%d) fail \n", func_name, fimg->rotate); + #endif + return false; + } + + FimgRect fimgSrcRect = {fimg->srcX, fimg->srcY, + fimg->srcW, fimg->srcH, + (fimg->srcFWStride / fimg->srcBPP), fimg->srcFH, + srcColorFormat, + fimg->srcBPP, + fimg->srcAddr}; + + FimgRect fimgDstRect = {fimg->dstX, fimg->dstY, + fimg->dstW, fimg->dstH, + (fimg->dstFWStride / fimg->dstBPP), fimg->dstFH, + dstColorFormat, + fimg->dstBPP, + fimg->dstAddr}; + +#if FIMGAPI_HYBRID_USE + int ratio = FimgApiCheckPossibleHybrid(fimg); + if (ratio == 0) + ret = FIMGAPI_FINISHED; + else { + int temp_clipT = fimg->clipT; + fimg->clipT = fimg->clipT + ((fimg->clipB - fimg->clipT) / 10) * (10 - ratio); + + if ((temp_clipT >= fimg->clipT) || (fimg->clipB <= fimg->clipT)) { + SkDebugf("Invalid clip value: TBLR = (%d, %d, %d, %d), mT = %d", + temp_clipT, fimg->clipB, fimg->clipL, fimg->clipR, fimg->clipT); + return false; + } + + ret = FIMGAPI_HYBRID; + } +#else + ret = FIMGAPI_FINISHED; +#endif + +#if (FIMGAPI_COMPROMISE_USE == FALSE) + if (FimgApiCheckPossible_Clipping(fimg) == false) + return false; +#endif + + FimgClip fimgClip = {fimg->clipT, fimg->clipB, fimg->clipL, fimg->clipR}; + FimgFlag fimgFlag; + + if (ret == FIMGAPI_HYBRID) + fimgFlag = {rotate, alpha, 0, 0, 0, 0, 0, 0, 0, + G2D_CACHE_OP | G2D_INTERRUPT | G2D_HYBRID_MODE, fimg->xfermode, G2D_MEMORY_USER}; + else + fimgFlag = {rotate, alpha, 0, 0, 0, 0, 0, 0, 0, + G2D_CACHE_OP | G2D_INTERRUPT, fimg->xfermode, G2D_MEMORY_USER}; + + if (stretchFimgApi(&fimgSrcRect, &fimgDstRect, &fimgClip, &fimgFlag) < 0) + return false; + + return ret; +} + +int FimgApiSync(const char *func_name) +{ + if (SyncFimgApi() < 0) + return false; + + return true; +} +#endif -- cgit v1.1