OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 Google Inc. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. |
| 6 */ |
| 7 |
| 8 #include "SkCoreBlitters.h" |
| 9 #include "SkColorPriv.h" |
| 10 #include "SkShader.h" |
| 11 #include "SkUtils.h" |
| 12 #include "SkXfermode.h" |
| 13 #include "SkBlitMask.h" |
| 14 |
| 15 ////////////////////////////////////////////////////////////////////////////////
////// |
| 16 |
| 17 SkARGB32_Shader4f_Blitter::SkARGB32_Shader4f_Blitter(const SkPixmap& device, |
| 18 const SkPaint& paint, SkShader::Context* shaderContext) |
| 19 : INHERITED(device, paint, shaderContext) |
| 20 { |
| 21 const uint32_t shaderFlags = shaderContext->getFlags(); |
| 22 |
| 23 SkASSERT(shaderFlags & SkShader::kSupports4f_Flag); |
| 24 |
| 25 fBuffer = (SkPM4f*)sk_malloc_throw(device.width() * (sizeof(SkPM4f))); |
| 26 |
| 27 fState.fXfer = SkSafeRef(paint.getXfermode()); |
| 28 fState.fFlags = 0; |
| 29 if (shaderFlags & SkShader::kOpaqueAlpha_Flag) { |
| 30 fState.fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag; |
| 31 } |
| 32 if (device.info().isSRGB()) { |
| 33 fState.fFlags |= SkXfermode::kDstIsSRGB_PM4fFlag; |
| 34 } |
| 35 if (fState.fXfer) { |
| 36 fProc1 = fState.fXfer->getPM4fProc1(fState.fFlags); |
| 37 fProcN = fState.fXfer->getPM4fProcN(fState.fFlags); |
| 38 } else { |
| 39 fProc1 = SkXfermode::GetPM4fProc1(SkXfermode::kSrcOver_Mode, fState.fFla
gs); |
| 40 fProcN = SkXfermode::GetPM4fProcN(SkXfermode::kSrcOver_Mode, fState.fFla
gs); |
| 41 } |
| 42 |
| 43 fConstInY = SkToBool(shaderFlags & SkShader::kConstInY32_Flag); |
| 44 } |
| 45 |
| 46 SkARGB32_Shader4f_Blitter::~SkARGB32_Shader4f_Blitter() { |
| 47 SkSafeUnref(fState.fXfer); |
| 48 sk_free(fBuffer); |
| 49 } |
| 50 |
| 51 void SkARGB32_Shader4f_Blitter::blitH(int x, int y, int width) { |
| 52 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
| 53 |
| 54 uint32_t* device = fDevice.writable_addr32(x, y); |
| 55 fShaderContext->shadeSpan4f(x, y, fBuffer, width); |
| 56 fProcN(fState, device, fBuffer, width, nullptr); |
| 57 } |
| 58 |
| 59 void SkARGB32_Shader4f_Blitter::blitRect(int x, int y, int width, int height) { |
| 60 SkASSERT(x >= 0 && y >= 0 && |
| 61 x + width <= fDevice.width() && y + height <= fDevice.height()); |
| 62 |
| 63 uint32_t* device = fDevice.writable_addr32(x, y); |
| 64 size_t deviceRB = fDevice.rowBytes(); |
| 65 |
| 66 if (fConstInY) { |
| 67 fShaderContext->shadeSpan4f(x, y, fBuffer, width); |
| 68 do { |
| 69 fProcN(fState, device, fBuffer, width, nullptr); |
| 70 y += 1; |
| 71 device = (uint32_t*)((char*)device + deviceRB); |
| 72 } while (--height > 0); |
| 73 } else { |
| 74 do { |
| 75 fShaderContext->shadeSpan4f(x, y, fBuffer, width); |
| 76 fProcN(fState, device, fBuffer, width, nullptr); |
| 77 y += 1; |
| 78 device = (uint32_t*)((char*)device + deviceRB); |
| 79 } while (--height > 0); |
| 80 } |
| 81 } |
| 82 |
| 83 void SkARGB32_Shader4f_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[
], |
| 84 const int16_t runs[]) { |
| 85 uint32_t* device = fDevice.writable_addr32(x, y); |
| 86 |
| 87 for (;;) { |
| 88 int count = *runs; |
| 89 if (count <= 0) { |
| 90 break; |
| 91 } |
| 92 int aa = *antialias; |
| 93 if (aa) { |
| 94 fShaderContext->shadeSpan4f(x, y, fBuffer, count); |
| 95 if (aa == 255) { |
| 96 fProcN(fState, device, fBuffer, count, nullptr); |
| 97 } else { |
| 98 // count is almost always 1 |
| 99 for (int i = count - 1; i >= 0; --i) { |
| 100 fProcN(fState, &device[i], &fBuffer[i], 1, antialias); |
| 101 } |
| 102 } |
| 103 } |
| 104 device += count; |
| 105 runs += count; |
| 106 antialias += count; |
| 107 x += count; |
| 108 } |
| 109 } |
| 110 |
| 111 void SkARGB32_Shader4f_Blitter::blitMask(const SkMask& mask, const SkIRect& clip
) { |
| 112 // we only handle kA8 |
| 113 if (SkMask::kA8_Format != mask.fFormat) { |
| 114 this->INHERITED::blitMask(mask, clip); |
| 115 return; |
| 116 } |
| 117 |
| 118 SkASSERT(mask.fBounds.contains(clip)); |
| 119 |
| 120 const int x = clip.fLeft; |
| 121 const int width = clip.width(); |
| 122 int y = clip.fTop; |
| 123 int height = clip.height(); |
| 124 |
| 125 char* dstRow = (char*)fDevice.writable_addr32(x, y); |
| 126 const size_t dstRB = fDevice.rowBytes(); |
| 127 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); |
| 128 const size_t maskRB = mask.fRowBytes; |
| 129 |
| 130 do { |
| 131 fShaderContext->shadeSpan4f(x, y, fBuffer, width); |
| 132 fProcN(fState, reinterpret_cast<SkPMColor*>(dstRow), fBuffer, width, mas
kRow); |
| 133 dstRow += dstRB; |
| 134 maskRow += maskRB; |
| 135 y += 1; |
| 136 } while (--height > 0); |
| 137 } |
| 138 |
| 139 void SkARGB32_Shader4f_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { |
| 140 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); |
| 141 |
| 142 uint32_t* device = fDevice.writable_addr32(x, y); |
| 143 size_t deviceRB = fDevice.rowBytes(); |
| 144 |
| 145 if (fConstInY) { |
| 146 fShaderContext->shadeSpan4f(x, y, fBuffer, 1); |
| 147 do { |
| 148 fProcN(fState, device, fBuffer, 1, &alpha); |
| 149 device = (uint32_t*)((char*)device + deviceRB); |
| 150 } while (--height > 0); |
| 151 } else { |
| 152 do { |
| 153 fShaderContext->shadeSpan4f(x, y, fBuffer, 1); |
| 154 fProcN(fState, device, fBuffer, 1, &alpha); |
| 155 y += 1; |
| 156 device = (uint32_t*)((char*)device + deviceRB); |
| 157 } while (--height > 0); |
| 158 } |
| 159 } |
OLD | NEW |