aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/SkBlitter_ARGB32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkBlitter_ARGB32.cpp')
-rw-r--r--src/core/SkBlitter_ARGB32.cpp325
1 files changed, 77 insertions, 248 deletions
diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp
index dec355a..24ab330 100644
--- a/src/core/SkBlitter_ARGB32.cpp
+++ b/src/core/SkBlitter_ARGB32.cpp
@@ -1,116 +1,19 @@
-/* libs/graphics/sgl/SkBlitter_ARGB32.cpp
-**
-** Copyright 2006, 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.
-*/
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
#include "SkCoreBlitters.h"
#include "SkColorPriv.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkXfermode.h"
-
-#if defined(SK_SUPPORT_LCDTEXT)
-namespace skia_blitter_support {
-// subpixel helper functions from SkBlitter_ARGB32_Subpixel.cpp
-uint32_t* adjustForSubpixelClip(const SkMask& mask,
- const SkIRect& clip, const SkBitmap& device,
- int* widthAdjustment, int* heightAdjustment,
- const uint32_t** alpha32);
-extern uint32_t BlendLCDPixelWithColor(const uint32_t alphaPixel, const uint32_t originalPixel,
- const uint32_t sourcePixel);
-extern uint32_t BlendLCDPixelWithOpaqueColor(const uint32_t alphaPixel, const uint32_t originalPixel,
- const uint32_t sourcePixel);
-extern uint32_t BlendLCDPixelWithBlack(const uint32_t alphaPixel, const uint32_t originalPixel);
-}
-
-using namespace skia_blitter_support;
-#endif
+#include "SkBlitMask.h"
///////////////////////////////////////////////////////////////////////////////
-static inline int upscale31To32(int value) {
- SkASSERT((unsigned)value <= 31);
- return value + (value >> 4);
-}
-
-static inline int blend32(int src, int dst, int scale) {
- SkASSERT((unsigned)src <= 0xFF);
- SkASSERT((unsigned)dst <= 0xFF);
- SkASSERT((unsigned)scale <= 32);
- return dst + ((src - dst) * scale >> 5);
-}
-
-static void blit_lcd16_opaque(SkPMColor dst[], const uint16_t src[],
- SkPMColor color, int width) {
- int srcR = SkGetPackedR32(color);
- int srcG = SkGetPackedG32(color);
- int srcB = SkGetPackedB32(color);
-
- for (int i = 0; i < width; i++) {
- uint16_t mask = src[i];
- if (0 == mask) {
- continue;
- }
-
- SkPMColor d = dst[i];
-
- /* We want all of these in 5bits, hence the shifts in case one of them
- * (green) is 6bits.
- */
- int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
- int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
- int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
-
- // Now upscale them to 0..256, so we can use SkAlphaBlend
- maskR = upscale31To32(maskR);
- maskG = upscale31To32(maskG);
- maskB = upscale31To32(maskB);
-
- int maskA = SkMax32(SkMax32(maskR, maskG), maskB);
-
- int dstA = SkGetPackedA32(d);
- int dstR = SkGetPackedR32(d);
- int dstG = SkGetPackedG32(d);
- int dstB = SkGetPackedB32(d);
-
- dst[i] = SkPackARGB32(blend32(0xFF, dstA, maskA),
- blend32(srcR, dstR, maskR),
- blend32(srcG, dstG, maskG),
- blend32(srcB, dstB, maskB));
- }
-}
-
-static void blitmask_lcd16(const SkBitmap& device, const SkMask& mask,
- const SkIRect& clip, SkPMColor srcColor) {
- int x = clip.fLeft;
- int y = clip.fTop;
- int width = clip.width();
- int height = clip.height();
-
- SkPMColor* dstRow = device.getAddr32(x, y);
- const uint16_t* srcRow = mask.getAddrLCD16(x, y);
-
- do {
- blit_lcd16_opaque(dstRow, srcRow, srcColor, width);
- dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
- srcRow = (const uint16_t*)((const char*)srcRow + mask.fRowBytes);
- } while (--height != 0);
-}
-
-//////////////////////////////////////////////////////////////////////////////////////
-
static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
const SkIRect& clip, SkPMColor srcColor) {
U8CPU alpha = SkGetPackedA32(srcColor);
@@ -126,7 +29,7 @@ static void SkARGB32_Blit32(const SkBitmap& device, const SkMask& mask,
int height = clip.height();
SkPMColor* dstRow = device.getAddr32(x, y);
- const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr(x, y));
+ const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y));
do {
proc(dstRow, srcRow, width, alpha);
@@ -150,9 +53,6 @@ SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
fColor32Proc = SkBlitRow::ColorProcFactory();
-
- // init the pro for blitmask
- fBlitMaskProc = SkBlitMask::Factory(SkBitmap::kARGB_8888_Config, color);
}
const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
@@ -254,84 +154,33 @@ void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
return;
}
+ if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
+ return;
+ }
+
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
- return;
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
- return;
- } else if (SkMask::kLCD16_Format == mask.fFormat) {
- blitmask_lcd16(fDevice, mask, clip, fPMColor);
- return;
}
-
- int x = clip.fLeft;
- int y = clip.fTop;
-
- fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
- SkBitmap::kARGB_8888_Config,
- mask.getAddr(x, y), mask.fRowBytes,
- fColor, clip.width(), clip.height());
}
void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
const SkIRect& clip) {
SkASSERT(mask.fBounds.contains(clip));
+ if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
+ return;
+ }
+
if (mask.fFormat == SkMask::kBW_Format) {
SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
- return;
} else if (SkMask::kARGB32_Format == mask.fFormat) {
SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
- return;
- } else if (SkMask::kLCD16_Format == mask.fFormat) {
- blitmask_lcd16(fDevice, mask, clip, fPMColor);
- return;
}
-
- int x = clip.fLeft;
- int y = clip.fTop;
- int width = clip.width();
- int height = clip.height();
-
-#if defined(SK_SUPPORT_LCDTEXT)
- const bool lcdMode = mask.fFormat == SkMask::kHorizontalLCD_Format;
- const bool verticalLCDMode = mask.fFormat == SkMask::kVerticalLCD_Format;
-
- // In LCD mode the masks have either an extra couple of rows or columns on the edges.
- if (lcdMode || verticalLCDMode) {
- int widthAdjustment, heightAdjustment;
- const uint32_t* alpha32;
- uint32_t* device = adjustForSubpixelClip(mask, clip, fDevice, &widthAdjustment, &heightAdjustment, &alpha32);
-
- width += widthAdjustment;
- height += heightAdjustment;
-
- unsigned devRB = fDevice.rowBytes() - (width << 2);
- unsigned alphaExtraRowWords = mask.rowWordsLCD() - width;
- SkPMColor srcColor = fPMColor;
-
- do {
- unsigned w = width;
- do {
- const uint32_t alphaPixel = *alpha32++;
- const uint32_t originalPixel = *device;
- *device++ = BlendLCDPixelWithOpaqueColor(alphaPixel, originalPixel, srcColor);
- } while (--w != 0);
- device = (uint32_t*)((char*)device + devRB);
- alpha32 += alphaExtraRowWords;
- } while (--height != 0);
-
- return;
- }
-#endif
-
- fBlitMaskProc(fDevice.getAddr32(x, y), fDevice.rowBytes(),
- SkBitmap::kARGB_8888_Config,
- mask.getAddr(x, y), mask.fRowBytes, fColor, width, height);
}
-//////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
if (alpha == 0 || fSrcA == 0) {
@@ -346,17 +195,9 @@ void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
}
unsigned dst_scale = 255 - SkGetPackedA32(color);
- uint32_t prevDst = ~device[0];
- uint32_t result SK_INIT_TO_AVOID_WARNING;
uint32_t rowBytes = fDevice.rowBytes();
-
while (--height >= 0) {
- uint32_t dst = device[0];
- if (dst != prevDst) {
- result = color + SkAlphaMulQ(dst, dst_scale);
- prevDst = dst;
- }
- device[0] = result;
+ device[0] = color + SkAlphaMulQ(device[0], dst_scale);
device = (uint32_t*)((char*)device + rowBytes);
}
}
@@ -384,74 +225,6 @@ void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
///////////////////////////////////////////////////////////////////////
-void SkARGB32_Black_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
- SkASSERT(mask.fBounds.contains(clip));
-
- if (mask.fFormat == SkMask::kBW_Format) {
- SkPMColor black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
-
- SkARGB32_BlitBW(fDevice, mask, clip, black);
- } else if (SkMask::kARGB32_Format == mask.fFormat) {
- SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
- } else if (SkMask::kLCD16_Format == mask.fFormat) {
- blitmask_lcd16(fDevice, mask, clip, fPMColor);
- } else {
-#if defined(SK_SUPPORT_LCDTEXT)
- const bool lcdMode = mask.fFormat == SkMask::kHorizontalLCD_Format;
- const bool verticalLCDMode = mask.fFormat == SkMask::kVerticalLCD_Format;
-#endif
-
- // In LCD mode the masks have either an extra couple of rows or columns on the edges.
- unsigned width = clip.width();
- unsigned height = clip.height();
-
- SkASSERT((int)height > 0);
- SkASSERT((int)width > 0);
-
-#if defined(SK_SUPPORT_LCDTEXT)
- if (lcdMode || verticalLCDMode) {
- int widthAdjustment, heightAdjustment;
- const uint32_t* alpha32;
- uint32_t* device = adjustForSubpixelClip(mask, clip, fDevice, &widthAdjustment, &heightAdjustment, &alpha32);
-
- width += widthAdjustment;
- height += heightAdjustment;
-
- unsigned deviceRB = fDevice.rowBytes() - (width << 2);
- unsigned alphaExtraRowWords = mask.rowWordsLCD() - width;
-
- do {
- unsigned w = width;
- do {
- const uint32_t alphaPixel = *alpha32++;
- const uint32_t originalPixel = *device;
- *device++ = BlendLCDPixelWithBlack(alphaPixel, originalPixel);
- } while (--w != 0);
- device = (uint32_t*)((char*)device + deviceRB);
- alpha32 += alphaExtraRowWords;
- } while (--height != 0);
-
- return;
- }
-#endif
-
- uint32_t* device = fDevice.getAddr32(clip.fLeft, clip.fTop);
- unsigned maskRB = mask.fRowBytes - width;
- unsigned deviceRB = fDevice.rowBytes() - (width << 2);
- const uint8_t* alpha = mask.getAddr(clip.fLeft, clip.fTop);
- do {
- unsigned w = width;
- do {
- unsigned aa = *alpha++;
- *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
- device += 1;
- } while (--w != 0);
- device = (uint32_t*)((char*)device + deviceRB);
- alpha += maskRB;
- } while (--height != 0);
- }
-}
-
void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
uint32_t* device = fDevice.getAddr32(x, y);
@@ -483,7 +256,7 @@ void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
}
}
-//////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
const SkPaint& paint) : INHERITED(device, paint) {
@@ -525,8 +298,6 @@ void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
}
}
-///////////////////////////////////////////////////////////////////////////////////////////////
-
void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
SkPMColor* span = fBuffer;
@@ -600,3 +371,61 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
}
}
}
+
+void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
+ // we only handle kA8 with an xfermode
+ if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
+ this->INHERITED::blitMask(mask, clip);
+ return;
+ }
+
+ SkASSERT(mask.fBounds.contains(clip));
+
+ SkBlitMask::RowProc proc = NULL;
+ if (!fXfermode) {
+ unsigned flags = 0;
+ if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
+ flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
+ }
+ proc = SkBlitMask::RowFactory(SkBitmap::kARGB_8888_Config, mask.fFormat,
+ (SkBlitMask::RowFlags)flags);
+ if (NULL == proc) {
+ this->INHERITED::blitMask(mask, clip);
+ return;
+ }
+ }
+
+ const int x = clip.fLeft;
+ const int width = clip.width();
+ int y = clip.fTop;
+ int height = clip.height();
+
+ char* dstRow = (char*)fDevice.getAddr32(x, y);
+ const size_t dstRB = fDevice.rowBytes();
+ const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
+ const size_t maskRB = mask.fRowBytes;
+
+ SkShader* shader = fShader;
+ SkPMColor* span = fBuffer;
+
+ if (fXfermode) {
+ SkASSERT(SkMask::kA8_Format == mask.fFormat);
+ SkXfermode* xfer = fXfermode;
+ do {
+ shader->shadeSpan(x, y, span, width);
+ xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow);
+ dstRow += dstRB;
+ maskRow += maskRB;
+ y += 1;
+ } while (--height > 0);
+ } else {
+ do {
+ shader->shadeSpan(x, y, span, width);
+ proc(dstRow, maskRow, span, width);
+ dstRow += dstRB;
+ maskRow += maskRB;
+ y += 1;
+ } while (--height > 0);
+ }
+}
+