| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCoreBlitters.h" | 8 #include "SkCoreBlitters.h" |
| 9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkShader.h" | 10 #include "SkShader.h" |
| 11 #include "SkUtils.h" | 11 #include "SkUtils.h" |
| 12 #include "SkXfermode.h" | 12 #include "SkXfermode.h" |
| 13 #include "SkBlitMask.h" | 13 #include "SkBlitMask.h" |
| 14 #include "SkTemplates.h" | 14 #include "SkTemplates.h" |
| 15 #include "SkPM4f.h" | 15 #include "SkPM4f.h" |
| 16 | 16 |
| 17 template <typename State> class SkState_Blitter : public SkRasterBlitter { | 17 template <typename State> class SkState_Blitter : public SkRasterBlitter { |
| 18 typedef SkRasterBlitter INHERITED; | 18 typedef SkRasterBlitter INHERITED; |
| 19 State fState; | 19 State fState; |
| 20 | 20 |
| 21 public: | 21 public: |
| 22 SkState_Blitter(const SkPixmap& device, const SkPaint& paint) | 22 SkState_Blitter(const SkPixmap& device, const SkPaint& paint) |
| 23 : INHERITED(device) | 23 : INHERITED(device) |
| 24 , fState(device.info(), paint, nullptr) | 24 , fState(device.info(), paint, nullptr) |
| 25 {} | 25 {} |
| 26 | 26 |
| 27 void blitH(int x, int y, int width) override { | 27 void blitH(int x, int y, int width) override { |
| 28 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); | 28 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
| 29 | 29 |
| 30 fState.fProc1(fState, State::WritableAddr(fDevice, x, y), fState.fPM4f,
width, nullptr); | 30 fState.fProc1(fState.fXfer, State::WritableAddr(fDevice, x, y), |
| 31 &fState.fPM4f, width, nullptr); |
| 31 } | 32 } |
| 32 | 33 |
| 33 void blitV(int x, int y, int height, SkAlpha alpha) override { | 34 void blitV(int x, int y, int height, SkAlpha alpha) override { |
| 34 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); | 35 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); |
| 35 | 36 |
| 36 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 37 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 37 size_t deviceRB = fDevice.rowBytes(); | 38 size_t deviceRB = fDevice.rowBytes(); |
| 38 | 39 |
| 39 for (int i = 0; i < height; ++i) { | 40 for (int i = 0; i < height; ++i) { |
| 40 fState.fProc1(fState, device, fState.fPM4f, 1, &alpha); | 41 fState.fProc1(fState.fXfer, device, &fState.fPM4f, 1, &alpha); |
| 41 device = (typename State::DstType*)((char*)device + deviceRB); | 42 device = (typename State::DstType*)((char*)device + deviceRB); |
| 42 } | 43 } |
| 43 } | 44 } |
| 44 | 45 |
| 45 void blitRect(int x, int y, int width, int height) override { | 46 void blitRect(int x, int y, int width, int height) override { |
| 46 SkASSERT(x >= 0 && y >= 0 && | 47 SkASSERT(x >= 0 && y >= 0 && |
| 47 x + width <= fDevice.width() && y + height <= fDevice.height())
; | 48 x + width <= fDevice.width() && y + height <= fDevice.height())
; |
| 48 | 49 |
| 49 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 50 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 50 size_t deviceRB = fDevice.rowBytes(); | 51 size_t deviceRB = fDevice.rowBytes(); |
| 51 | 52 |
| 52 do { | 53 do { |
| 53 fState.fProc1(fState, device, fState.fPM4f, width, nullptr); | 54 fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, nullptr); |
| 54 y += 1; | 55 y += 1; |
| 55 device = (typename State::DstType*)((char*)device + deviceRB); | 56 device = (typename State::DstType*)((char*)device + deviceRB); |
| 56 } while (--height > 0); | 57 } while (--height > 0); |
| 57 } | 58 } |
| 58 | 59 |
| 59 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { | 60 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { |
| 60 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 61 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 61 | 62 |
| 62 for (;;) { | 63 for (;;) { |
| 63 int count = *runs; | 64 int count = *runs; |
| 64 if (count <= 0) { | 65 if (count <= 0) { |
| 65 break; | 66 break; |
| 66 } | 67 } |
| 67 int aa = *antialias; | 68 int aa = *antialias; |
| 68 if (aa) { | 69 if (aa) { |
| 69 if (aa == 255) { | 70 if (aa == 255) { |
| 70 fState.fProc1(fState, device, fState.fPM4f, count, nullptr); | 71 fState.fProc1(fState.fXfer, device, &fState.fPM4f, count, nu
llptr); |
| 71 } else { | 72 } else { |
| 72 for (int i = 0; i < count; ++i) { | 73 for (int i = 0; i < count; ++i) { |
| 73 fState.fProc1(fState, &device[i], fState.fPM4f, 1, antia
lias); | 74 fState.fProc1(fState.fXfer, &device[i], &fState.fPM4f, 1
, antialias); |
| 74 } | 75 } |
| 75 } | 76 } |
| 76 } | 77 } |
| 77 device += count; | 78 device += count; |
| 78 runs += count; | 79 runs += count; |
| 79 antialias += count; | 80 antialias += count; |
| 80 x += count; | 81 x += count; |
| 81 } | 82 } |
| 82 } | 83 } |
| 83 | 84 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 const int width = clip.width(); | 118 const int width = clip.width(); |
| 118 const int y = clip.fTop; | 119 const int y = clip.fTop; |
| 119 const int height = clip.height(); | 120 const int height = clip.height(); |
| 120 | 121 |
| 121 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 122 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 122 const size_t dstRB = fDevice.rowBytes(); | 123 const size_t dstRB = fDevice.rowBytes(); |
| 123 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); | 124 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); |
| 124 const size_t maskRB = mask.fRowBytes; | 125 const size_t maskRB = mask.fRowBytes; |
| 125 | 126 |
| 126 for (int i = 0; i < height; ++i) { | 127 for (int i = 0; i < height; ++i) { |
| 127 fState.fProc1(fState, device, fState.fPM4f, width, maskRow); | 128 fState.fProc1(fState.fXfer, device, &fState.fPM4f, width, maskRow); |
| 128 device = (typename State::DstType*)((char*)device + dstRB); | 129 device = (typename State::DstType*)((char*)device + dstRB); |
| 129 maskRow += maskRB; | 130 maskRow += maskRB; |
| 130 } | 131 } |
| 131 } | 132 } |
| 132 }; | 133 }; |
| 133 | 134 |
| 134 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 135 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 135 | 136 |
| 136 template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter
{ | 137 template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter
{ |
| 137 public: | 138 public: |
| 138 SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, | 139 SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, |
| 139 SkShader::Context* shaderContext) | 140 SkShader::Context* shaderContext) |
| 140 : INHERITED(device, paint, shaderContext) | 141 : INHERITED(device, paint, shaderContext) |
| 141 , fState(device.info(), paint, shaderContext) | 142 , fState(device.info(), paint, shaderContext) |
| 142 {} | 143 {} |
| 143 | 144 |
| 144 void blitH(int x, int y, int width) override { | 145 void blitH(int x, int y, int width) override { |
| 145 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); | 146 SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); |
| 146 | 147 |
| 147 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 148 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 148 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 149 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
| 149 fState.fProcN(fState, device, fState.fBuffer, width, nullptr); | 150 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
| 150 } | 151 } |
| 151 | 152 |
| 152 void blitV(int x, int y, int height, SkAlpha alpha) override { | 153 void blitV(int x, int y, int height, SkAlpha alpha) override { |
| 153 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); | 154 SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); |
| 154 | 155 |
| 155 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 156 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 156 size_t deviceRB = fDevice.rowBytes(); | 157 size_t deviceRB = fDevice.rowBytes(); |
| 157 const int bottom = y + height; | 158 const int bottom = y + height; |
| 158 | 159 |
| 159 if (fConstInY) { | 160 if (fConstInY) { |
| 160 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 161 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
| 161 } | 162 } |
| 162 for (; y < bottom; ++y) { | 163 for (; y < bottom; ++y) { |
| 163 if (!fConstInY) { | 164 if (!fConstInY) { |
| 164 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); | 165 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, 1); |
| 165 } | 166 } |
| 166 fState.fProcN(fState, device, fState.fBuffer, 1, &alpha); | 167 fState.fProcN(fState.fXfer, device, fState.fBuffer, 1, &alpha); |
| 167 device = (typename State::DstType*)((char*)device + deviceRB); | 168 device = (typename State::DstType*)((char*)device + deviceRB); |
| 168 } | 169 } |
| 169 } | 170 } |
| 170 | 171 |
| 171 void blitRect(int x, int y, int width, int height) override { | 172 void blitRect(int x, int y, int width, int height) override { |
| 172 SkASSERT(x >= 0 && y >= 0 && | 173 SkASSERT(x >= 0 && y >= 0 && |
| 173 x + width <= fDevice.width() && y + height <= fDevice.height())
; | 174 x + width <= fDevice.width() && y + height <= fDevice.height())
; |
| 174 | 175 |
| 175 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 176 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 176 size_t deviceRB = fDevice.rowBytes(); | 177 size_t deviceRB = fDevice.rowBytes(); |
| 177 const int bottom = y + height; | 178 const int bottom = y + height; |
| 178 | 179 |
| 179 if (fConstInY) { | 180 if (fConstInY) { |
| 180 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 181 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
| 181 } | 182 } |
| 182 for (; y < bottom; ++y) { | 183 for (; y < bottom; ++y) { |
| 183 if (!fConstInY) { | 184 if (!fConstInY) { |
| 184 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 185 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
| 185 } | 186 } |
| 186 fState.fProcN(fState, device, fState.fBuffer, width, nullptr); | 187 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, nullptr); |
| 187 device = (typename State::DstType*)((char*)device + deviceRB); | 188 device = (typename State::DstType*)((char*)device + deviceRB); |
| 188 } | 189 } |
| 189 } | 190 } |
| 190 | 191 |
| 191 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { | 192 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]
) override { |
| 192 typename State::DstType* device = State::WritableAddr(fDevice, x, y); | 193 typename State::DstType* device = State::WritableAddr(fDevice, x, y); |
| 193 | 194 |
| 194 for (;;) { | 195 for (;;) { |
| 195 int count = *runs; | 196 int count = *runs; |
| 196 if (count <= 0) { | 197 if (count <= 0) { |
| 197 break; | 198 break; |
| 198 } | 199 } |
| 199 int aa = *antialias; | 200 int aa = *antialias; |
| 200 if (aa) { | 201 if (aa) { |
| 201 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); | 202 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); |
| 202 if (aa == 255) { | 203 if (aa == 255) { |
| 203 fState.fProcN(fState, device, fState.fBuffer, count, nullptr
); | 204 fState.fProcN(fState.fXfer, device, fState.fBuffer, count, n
ullptr); |
| 204 } else { | 205 } else { |
| 205 for (int i = 0; i < count; ++i) { | 206 for (int i = 0; i < count; ++i) { |
| 206 fState.fProcN(fState, &device[i], &fState.fBuffer[i], 1,
antialias); | 207 fState.fProcN(fState.fXfer, &device[i], &fState.fBuffer[
i], 1, antialias); |
| 207 } | 208 } |
| 208 } | 209 } |
| 209 } | 210 } |
| 210 device += count; | 211 device += count; |
| 211 runs += count; | 212 runs += count; |
| 212 antialias += count; | 213 antialias += count; |
| 213 x += count; | 214 x += count; |
| 214 } | 215 } |
| 215 } | 216 } |
| 216 | 217 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); | 261 const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); |
| 261 const size_t maskRB = mask.fRowBytes; | 262 const size_t maskRB = mask.fRowBytes; |
| 262 | 263 |
| 263 if (fConstInY) { | 264 if (fConstInY) { |
| 264 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 265 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
| 265 } | 266 } |
| 266 for (; y < clip.fBottom; ++y) { | 267 for (; y < clip.fBottom; ++y) { |
| 267 if (!fConstInY) { | 268 if (!fConstInY) { |
| 268 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); | 269 fShaderContext->shadeSpan4f(x, y, fState.fBuffer, width); |
| 269 } | 270 } |
| 270 fState.fProcN(fState, device, fState.fBuffer, width, maskRow); | 271 fState.fProcN(fState.fXfer, device, fState.fBuffer, width, maskRow); |
| 271 device = (typename State::DstType*)((char*)device + deviceRB); | 272 device = (typename State::DstType*)((char*)device + deviceRB); |
| 272 maskRow += maskRB; | 273 maskRow += maskRB; |
| 273 } | 274 } |
| 274 } | 275 } |
| 275 | 276 |
| 276 private: | 277 private: |
| 277 State fState; | 278 State fState; |
| 278 | 279 |
| 279 typedef SkShaderBlitter INHERITED; | 280 typedef SkShaderBlitter INHERITED; |
| 280 }; | 281 }; |
| 281 | 282 |
| 282 ////////////////////////////////////////////////////////////////////////////////
////// | 283 ////////////////////////////////////////////////////////////////////////////////
////// |
| 283 | 284 |
| 284 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { | 285 static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderConte
xt) { |
| 285 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) | 286 return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqu
eAlpha_Flag) |
| 286 : 0xFF == paint.getAlpha(); | 287 : 0xFF == paint.getAlpha(); |
| 287 } | 288 } |
| 288 | 289 |
| 289 struct State32 : SkXfermode::PM4fState { | 290 struct State4f { |
| 290 typedef uint32_t DstType; | 291 State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { |
| 291 | 292 fXfer = paint.getXfermode(); |
| 292 SkXfermode::PM4fProc1 fProc1; | |
| 293 SkXfermode::PM4fProcN fProcN; | |
| 294 SkPM4f fPM4f; | |
| 295 SkPM4f* fBuffer; | |
| 296 | |
| 297 State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { | |
| 298 fXfer = SkSafeRef(paint.getXfermode()); | |
| 299 fFlags = 0; | |
| 300 if (is_opaque(paint, shaderContext)) { | |
| 301 fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag; | |
| 302 } | |
| 303 if (info.isSRGB()) { | |
| 304 fFlags |= SkXfermode::kDstIsSRGB_PM4fFlag; | |
| 305 } | |
| 306 if (fXfer) { | |
| 307 fProc1 = fXfer->getPM4fProc1(fFlags); | |
| 308 fProcN = fXfer->getPM4fProcN(fFlags); | |
| 309 } else { | |
| 310 fProc1 = SkXfermode::GetPM4fProc1(SkXfermode::kSrcOver_Mode, fFlags)
; | |
| 311 fProcN = SkXfermode::GetPM4fProcN(SkXfermode::kSrcOver_Mode, fFlags)
; | |
| 312 } | |
| 313 | |
| 314 fBuffer = nullptr; | |
| 315 if (shaderContext) { | 293 if (shaderContext) { |
| 316 fBuffer = new SkPM4f[info.width()]; | 294 fBuffer.reset(info.width()); |
| 317 } else { | 295 } else { |
| 318 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); | 296 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); |
| 319 } | 297 } |
| 298 fFlags = 0; |
| 299 } |
| 300 |
| 301 SkXfermode* fXfer; |
| 302 SkPM4f fPM4f; |
| 303 SkAutoTMalloc<SkPM4f> fBuffer; |
| 304 uint32_t fFlags; |
| 305 }; |
| 306 |
| 307 struct State32 : State4f { |
| 308 typedef uint32_t DstType; |
| 309 |
| 310 SkXfermode::D32Proc fProc1; |
| 311 SkXfermode::D32Proc fProcN; |
| 312 |
| 313 State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) |
| 314 : State4f(info, paint, shaderContext) |
| 315 { |
| 316 if (is_opaque(paint, shaderContext)) { |
| 317 fFlags |= SkXfermode::kSrcIsOpaque_D32Flag; |
| 318 } |
| 319 if (info.isSRGB()) { |
| 320 fFlags |= SkXfermode::kDstIsSRGB_D32Flag; |
| 321 } |
| 322 fProc1 = SkXfermode::GetD32Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle
_D32Flag); |
| 323 fProcN = SkXfermode::GetD32Proc(fXfer, fFlags); |
| 320 } | 324 } |
| 321 | 325 |
| 322 ~State32() { | |
| 323 SkSafeUnref(fXfer); | |
| 324 delete[] fBuffer; | |
| 325 } | |
| 326 | |
| 327 SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const { | 326 SkXfermode::LCD32Proc getLCDProc(uint32_t oneOrManyFlag) const { |
| 328 uint32_t flags = fFlags & 1; | 327 uint32_t flags = fFlags & 1; |
| 329 if (!(fFlags & SkXfermode::kDstIsSRGB_PM4fFlag)) { | 328 if (!(fFlags & SkXfermode::kDstIsSRGB_D32Flag)) { |
| 330 flags |= SkXfermode::kDstIsLinearInt_LCDFlag; | 329 flags |= SkXfermode::kDstIsLinearInt_LCDFlag; |
| 331 } | 330 } |
| 332 return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag); | 331 return SkXfermode::GetLCD32Proc(flags | oneOrManyFlag); |
| 333 } | 332 } |
| 334 | 333 |
| 335 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { | 334 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { |
| 336 return device.writable_addr32(x, y); | 335 return device.writable_addr32(x, y); |
| 337 } | 336 } |
| 338 }; | 337 }; |
| 339 | 338 |
| 340 struct State64 : SkXfermode::U64State { | 339 struct State64 : State4f { |
| 341 typedef uint64_t DstType; | 340 typedef uint64_t DstType; |
| 342 | 341 |
| 343 SkXfermode::U64Proc1 fProc1; | 342 SkXfermode::D64Proc fProc1; |
| 344 SkXfermode::U64ProcN fProcN; | 343 SkXfermode::D64Proc fProcN; |
| 345 SkPM4f fPM4f; | |
| 346 SkPM4f* fBuffer; | |
| 347 | 344 |
| 348 State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) { | 345 State64(const SkImageInfo& info, const SkPaint& paint, const SkShader::Conte
xt* shaderContext) |
| 349 fXfer = SkSafeRef(paint.getXfermode()); | 346 : State4f(info, paint, shaderContext) |
| 350 fFlags = 0; | 347 { |
| 351 if (is_opaque(paint, shaderContext)) { | 348 if (is_opaque(paint, shaderContext)) { |
| 352 fFlags |= SkXfermode::kSrcIsOpaque_PM4fFlag; | 349 fFlags |= SkXfermode::kSrcIsOpaque_D64Flag; |
| 353 } | 350 } |
| 354 if (kRGBA_F16_SkColorType == info.colorType()) { | 351 if (kRGBA_F16_SkColorType == info.colorType()) { |
| 355 fFlags |= SkXfermode::kDstIsFloat16_U64Flag; | 352 fFlags |= SkXfermode::kDstIsFloat16_D64Flag; |
| 356 } | 353 } |
| 357 | 354 fProc1 = SkXfermode::GetD64Proc(fXfer, fFlags | SkXfermode::kSrcIsSingle
_D64Flag); |
| 358 SkXfermode::Mode mode; | 355 fProcN = SkXfermode::GetD64Proc(fXfer, fFlags); |
| 359 if (!SkXfermode::AsMode(fXfer, &mode)) { | |
| 360 mode = SkXfermode::kSrcOver_Mode; | |
| 361 } | |
| 362 fProc1 = SkXfermode::GetU64Proc1(mode, fFlags); | |
| 363 fProcN = SkXfermode::GetU64ProcN(mode, fFlags); | |
| 364 | |
| 365 fBuffer = nullptr; | |
| 366 if (shaderContext) { | |
| 367 fBuffer = new SkPM4f[info.width()]; | |
| 368 } else { | |
| 369 fPM4f = SkColor4f::FromColor(paint.getColor()).premul(); | |
| 370 } | |
| 371 } | 356 } |
| 372 | 357 |
| 373 ~State64() { | |
| 374 SkSafeUnref(fXfer); | |
| 375 delete[] fBuffer; | |
| 376 } | |
| 377 | |
| 378 SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const { | 358 SkXfermode::LCD64Proc getLCDProc(uint32_t oneOrManyFlag) const { |
| 379 uint32_t flags = fFlags & 1; | 359 uint32_t flags = fFlags & 1; |
| 380 if (!(fFlags & SkXfermode::kDstIsFloat16_U64Flag)) { | 360 if (!(fFlags & SkXfermode::kDstIsFloat16_D64Flag)) { |
| 381 flags |= SkXfermode::kDstIsLinearInt_LCDFlag; | 361 flags |= SkXfermode::kDstIsLinearInt_LCDFlag; |
| 382 } | 362 } |
| 383 return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag); | 363 return SkXfermode::GetLCD64Proc(flags | oneOrManyFlag); |
| 384 } | 364 } |
| 385 | 365 |
| 386 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { | 366 static DstType* WritableAddr(const SkPixmap& device, int x, int y) { |
| 387 return device.writable_addr64(x, y); | 367 return device.writable_addr64(x, y); |
| 388 } | 368 } |
| 389 }; | 369 }; |
| 390 | 370 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 408 SkShader::Context* shaderContext, | 388 SkShader::Context* shaderContext, |
| 409 SkTBlitterAllocator* allocator) { | 389 SkTBlitterAllocator* allocator) { |
| 410 return create<State32>(device, paint, shaderContext, allocator); | 390 return create<State32>(device, paint, shaderContext, allocator); |
| 411 } | 391 } |
| 412 | 392 |
| 413 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, | 393 SkBlitter* SkBlitter_ARGB64_Create(const SkPixmap& device, const SkPaint& paint, |
| 414 SkShader::Context* shaderContext, | 394 SkShader::Context* shaderContext, |
| 415 SkTBlitterAllocator* allocator) { | 395 SkTBlitterAllocator* allocator) { |
| 416 return create<State64>(device, paint, shaderContext, allocator); | 396 return create<State64>(device, paint, shaderContext, allocator); |
| 417 } | 397 } |
| OLD | NEW |