| File: | root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/skia/./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp |
| Warning: | line 237, column 17 Value stored to 'name' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 "src/core/SkRasterPipeline.h" |
| 9 | |
| 10 | #include "include/core/SkColorType.h" |
| 11 | #include "include/core/SkImageInfo.h" |
| 12 | #include "include/core/SkMatrix.h" |
| 13 | #include "include/private/base/SkDebug.h" |
| 14 | #include "include/private/base/SkTemplates.h" |
| 15 | #include "modules/skcms/skcms.h" |
| 16 | #include "src/base/SkVx.h" |
| 17 | #include "src/core/SkImageInfoPriv.h" |
| 18 | #include "src/core/SkOpts.h" |
| 19 | #include "src/core/SkRasterPipelineOpContexts.h" |
| 20 | #include "src/core/SkRasterPipelineOpList.h" |
| 21 | |
| 22 | #include <algorithm> |
| 23 | #include <cstring> |
| 24 | #include <vector> |
| 25 | |
| 26 | using namespace skia_private; |
| 27 | using Op = SkRasterPipelineOp; |
| 28 | |
| 29 | bool gForceHighPrecisionRasterPipeline; |
| 30 | |
| 31 | SkRasterPipeline::SkRasterPipeline(SkArenaAlloc* alloc) : fAlloc(alloc) { |
| 32 | this->reset(); |
| 33 | } |
| 34 | |
| 35 | void SkRasterPipeline::reset() { |
| 36 | // We intentionally leave the alloc alone here; we don't own it. |
| 37 | fRewindCtx = nullptr; |
| 38 | fStages = nullptr; |
| 39 | fTailPointer = nullptr; |
| 40 | fNumStages = 0; |
| 41 | fMemoryCtxInfos.clear(); |
| 42 | } |
| 43 | |
| 44 | void SkRasterPipeline::append(SkRasterPipelineOp op, void* ctx) { |
| 45 | SkASSERT(op != Op::uniform_color)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::uniform_color), 1) ? static_cast<void>(0 ) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 45, "op != Op::uniform_color"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); // Please use appendConstantColor(). |
| 46 | SkASSERT(op != Op::unbounded_uniform_color)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::unbounded_uniform_color), 1) ? static_cast< void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf ("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 46, "op != Op::unbounded_uniform_color"); ; sk_abort_no_print (); } while (false); } } while(false); }() ); // Please use appendConstantColor(). |
| 47 | SkASSERT(op != Op::set_rgb)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::set_rgb), 1) ? static_cast<void>(0) : [] { do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 47, "op != Op::set_rgb"); ; sk_abort_no_print(); } while (false ); } } while(false); }() ); // Please use appendSetRGB(). |
| 48 | SkASSERT(op != Op::unbounded_set_rgb)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::unbounded_set_rgb), 1) ? static_cast<void> (0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 48, "op != Op::unbounded_set_rgb"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); // Please use appendSetRGB(). |
| 49 | SkASSERT(op != Op::parametric)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::parametric), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 49, "op != Op::parametric"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); // Please use appendTransferFunction(). |
| 50 | SkASSERT(op != Op::gamma_)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::gamma_), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 50, "op != Op::gamma_"); ; sk_abort_no_print(); } while (false ); } } while(false); }() ); // Please use appendTransferFunction(). |
| 51 | SkASSERT(op != Op::PQish)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::PQish), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 51, "op != Op::PQish"); ; sk_abort_no_print(); } while (false ); } } while(false); }() ); // Please use appendTransferFunction(). |
| 52 | SkASSERT(op != Op::HLGish)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::HLGish), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 52, "op != Op::HLGish"); ; sk_abort_no_print(); } while (false ); } } while(false); }() ); // Please use appendTransferFunction(). |
| 53 | SkASSERT(op != Op::HLGinvish)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::HLGinvish), 1) ? static_cast<void>(0) : [ ]{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 53, "op != Op::HLGinvish"); ; sk_abort_no_print(); } while ( false); } } while(false); }() ); // Please use appendTransferFunction(). |
| 54 | SkASSERT(op != Op::stack_checkpoint)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::stack_checkpoint), 1) ? static_cast<void> (0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 54, "op != Op::stack_checkpoint"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); // Please use appendStackRewind(). |
| 55 | SkASSERT(op != Op::stack_rewind)static_cast<void>( __builtin_expect(static_cast<bool >(op != Op::stack_rewind), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 55, "op != Op::stack_rewind"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); // Please use appendStackRewind(). |
| 56 | this->uncheckedAppend(op, ctx); |
| 57 | } |
| 58 | |
| 59 | uint8_t* SkRasterPipeline::tailPointer() { |
| 60 | if (!fTailPointer) { |
| 61 | // All ops in the pipeline that use the tail value share the same value. |
| 62 | fTailPointer = fAlloc->make<uint8_t>(0xFF); |
| 63 | } |
| 64 | return fTailPointer; |
| 65 | } |
| 66 | |
| 67 | void SkRasterPipeline::uncheckedAppend(SkRasterPipelineOp op, void* ctx) { |
| 68 | bool isLoad = false, isStore = false; |
| 69 | SkColorType ct = kUnknown_SkColorType; |
| 70 | |
| 71 | #define COLOR_TYPE_CASE(stage_ct, sk_ct) \ |
| 72 | case Op::load_##stage_ct: \ |
| 73 | case Op::load_##stage_ct##_dst: \ |
| 74 | ct = sk_ct; \ |
| 75 | isLoad = true; \ |
| 76 | break; \ |
| 77 | case Op::store_##stage_ct: \ |
| 78 | ct = sk_ct; \ |
| 79 | isStore = true; \ |
| 80 | break; |
| 81 | |
| 82 | switch (op) { |
| 83 | COLOR_TYPE_CASE(a8, kAlpha_8_SkColorType) |
| 84 | COLOR_TYPE_CASE(565, kRGB_565_SkColorType) |
| 85 | COLOR_TYPE_CASE(4444, kARGB_4444_SkColorType) |
| 86 | COLOR_TYPE_CASE(8888, kRGBA_8888_SkColorType) |
| 87 | COLOR_TYPE_CASE(rg88, kR8G8_unorm_SkColorType) |
| 88 | COLOR_TYPE_CASE(16161616, kR16G16B16A16_unorm_SkColorType) |
| 89 | COLOR_TYPE_CASE(a16, kA16_unorm_SkColorType) |
| 90 | COLOR_TYPE_CASE(r16, kR16_unorm_SkColorType) |
| 91 | COLOR_TYPE_CASE(rg1616, kR16G16_unorm_SkColorType) |
| 92 | COLOR_TYPE_CASE(f16, kRGBA_F16_SkColorType) |
| 93 | COLOR_TYPE_CASE(af16, kA16_float_SkColorType) |
| 94 | COLOR_TYPE_CASE(rf16, kR16_float_SkColorType) |
| 95 | COLOR_TYPE_CASE(rgf16, kR16G16_float_SkColorType) |
| 96 | COLOR_TYPE_CASE(f32, kRGBA_F32_SkColorType) |
| 97 | COLOR_TYPE_CASE(1010102, kRGBA_1010102_SkColorType) |
| 98 | COLOR_TYPE_CASE(1010102_xr, kBGR_101010x_XR_SkColorType) |
| 99 | COLOR_TYPE_CASE(10101010_xr, kBGRA_10101010_XR_SkColorType) |
| 100 | COLOR_TYPE_CASE(10x6, kRGBA_10x6_SkColorType) |
| 101 | |
| 102 | #undef COLOR_TYPE_CASE |
| 103 | |
| 104 | case Op::debug_r: |
| 105 | case Op::debug_g: |
| 106 | case Op::debug_b: |
| 107 | case Op::debug_a: |
| 108 | case Op::debug_r_255: |
| 109 | case Op::debug_g_255: |
| 110 | case Op::debug_b_255: |
| 111 | case Op::debug_a_255: |
| 112 | case Op::debug_x: |
| 113 | case Op::debug_y: { |
| 114 | ct = kRGBA_8888_SkColorType; |
| 115 | isStore = true; |
| 116 | break; |
| 117 | } |
| 118 | // Odd stage that doesn't have a load variant (appendLoad uses load_a8 + alpha_to_red) |
| 119 | case Op::store_r8: { |
| 120 | ct = kR8_unorm_SkColorType; |
| 121 | isStore = true; |
| 122 | break; |
| 123 | } |
| 124 | case Op::srcover_rgba_8888: { |
| 125 | ct = kRGBA_8888_SkColorType; |
| 126 | isLoad = true; |
| 127 | isStore = true; |
| 128 | break; |
| 129 | } |
| 130 | case Op::scale_u8: |
| 131 | case Op::lerp_u8: { |
| 132 | ct = kAlpha_8_SkColorType; |
| 133 | isLoad = true; |
| 134 | break; |
| 135 | } |
| 136 | case Op::scale_565: |
| 137 | case Op::lerp_565: { |
| 138 | ct = kRGB_565_SkColorType; |
| 139 | isLoad = true; |
| 140 | break; |
| 141 | } |
| 142 | case Op::emboss: { |
| 143 | // Special-case, this op uses a context that holds *two* MemoryCtxs |
| 144 | SkRasterPipelineContexts::EmbossCtx* embossCtx = |
| 145 | (SkRasterPipelineContexts::EmbossCtx*)ctx; |
| 146 | this->addMemoryContext(&embossCtx->add, |
| 147 | SkColorTypeBytesPerPixel(kAlpha_8_SkColorType), |
| 148 | /*load=*/true, /*store=*/false); |
| 149 | this->addMemoryContext(&embossCtx->mul, |
| 150 | SkColorTypeBytesPerPixel(kAlpha_8_SkColorType), |
| 151 | /*load=*/true, /*store=*/false); |
| 152 | break; |
| 153 | } |
| 154 | case Op::init_lane_masks: { |
| 155 | auto* initCtx = (SkRasterPipelineContexts::InitLaneMasksCtx*)ctx; |
| 156 | initCtx->tail = this->tailPointer(); |
| 157 | break; |
| 158 | } |
| 159 | case Op::branch_if_all_lanes_active: { |
| 160 | auto* branchCtx = (SkRasterPipelineContexts::BranchIfAllLanesActiveCtx*)ctx; |
| 161 | branchCtx->tail = this->tailPointer(); |
| 162 | break; |
| 163 | } |
| 164 | default: |
| 165 | break; |
| 166 | } |
| 167 | |
| 168 | fStages = fAlloc->make<StageList>(StageList{fStages, op, ctx}); |
| 169 | fNumStages += 1; |
| 170 | |
| 171 | if (isLoad || isStore) { |
| 172 | SkASSERT(ct != kUnknown_SkColorType)static_cast<void>( __builtin_expect(static_cast<bool >(ct != kUnknown_SkColorType), 1) ? static_cast<void> (0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 172, "ct != kUnknown_SkColorType"); ; sk_abort_no_print(); } while (false); } } while(false); }() ); |
| 173 | this->addMemoryContext((SkRasterPipelineContexts::MemoryCtx*)ctx, |
| 174 | SkColorTypeBytesPerPixel(ct), |
| 175 | isLoad, |
| 176 | isStore); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | void SkRasterPipeline::append(SkRasterPipelineOp op, uintptr_t ctx) { |
| 181 | void* ptrCtx; |
| 182 | memcpy(&ptrCtx, &ctx, sizeof(ctx)); |
| 183 | this->append(op, ptrCtx); |
| 184 | } |
| 185 | |
| 186 | void SkRasterPipeline::extend(const SkRasterPipeline& src) { |
| 187 | if (src.empty()) { |
| 188 | return; |
| 189 | } |
| 190 | // Create a rewind context if `src` has one already, but we don't. If we _do_ already have one, |
| 191 | // we need to keep it, since we already have rewind ops that reference it. Either way, we need |
| 192 | // to rewrite all the rewind ops to point to _our_ rewind context; we only get that checkpoint. |
| 193 | if (src.fRewindCtx && !fRewindCtx) { |
| 194 | fRewindCtx = fAlloc->make<SkRasterPipelineContexts::RewindCtx>(); |
| 195 | } |
| 196 | auto stages = fAlloc->makeArrayDefault<StageList>(src.fNumStages); |
| 197 | |
| 198 | int n = src.fNumStages; |
| 199 | const StageList* st = src.fStages; |
| 200 | while (n --> 1) { |
| 201 | stages[n] = *st; |
| 202 | stages[n].prev = &stages[n-1]; |
| 203 | |
| 204 | // We make sure that all ops use _our_ stack context and tail pointer. |
| 205 | switch (stages[n].stage) { |
| 206 | case Op::stack_rewind: { |
| 207 | stages[n].ctx = fRewindCtx; |
| 208 | break; |
| 209 | } |
| 210 | case Op::init_lane_masks: { |
| 211 | auto* ctx = (SkRasterPipelineContexts::InitLaneMasksCtx*)stages[n].ctx; |
| 212 | ctx->tail = this->tailPointer(); |
| 213 | break; |
| 214 | } |
| 215 | case Op::branch_if_all_lanes_active: { |
| 216 | auto* ctx = (SkRasterPipelineContexts::BranchIfAllLanesActiveCtx*)stages[n].ctx; |
| 217 | ctx->tail = this->tailPointer(); |
| 218 | break; |
| 219 | } |
| 220 | default: |
| 221 | break; |
| 222 | } |
| 223 | |
| 224 | st = st->prev; |
| 225 | } |
| 226 | stages[0] = *st; |
| 227 | stages[0].prev = fStages; |
| 228 | |
| 229 | fStages = &stages[src.fNumStages - 1]; |
| 230 | fNumStages += src.fNumStages; |
| 231 | for (const SkRasterPipelineContexts::MemoryCtxInfo& info : src.fMemoryCtxInfos) { |
| 232 | this->addMemoryContext(info.context, info.bytesPerPixel, info.load, info.store); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | const char* SkRasterPipeline::GetOpName(SkRasterPipelineOp op) { |
| 237 | const char* name = ""; |
Value stored to 'name' during its initialization is never read | |
| 238 | switch (op) { |
| 239 | #define M(x) case Op::x: name = #x; break; |
| 240 | SK_RASTER_PIPELINE_OPS_ALL(M)M(move_src_dst) M(move_dst_src) M(swap_src_dst) M(clamp_01) M (clamp_a_01) M(clamp_gamut) M(premul) M(premul_dst) M(force_opaque ) M(force_opaque_dst) M(set_rgb) M(swap_rb) M(swap_rb_dst) M( black_color) M(white_color) M(uniform_color) M(uniform_color_dst ) M(seed_shader) M(load_a8) M(load_a8_dst) M(store_a8) M(gather_a8 ) M(load_565) M(load_565_dst) M(store_565) M(gather_565) M(load_4444 ) M(load_4444_dst) M(store_4444) M(gather_4444) M(load_8888) M (load_8888_dst) M(store_8888) M(gather_8888) M(load_rg88) M(load_rg88_dst ) M(store_rg88) M(gather_rg88) M(store_r8) M(alpha_to_gray) M (alpha_to_gray_dst) M(alpha_to_red) M(alpha_to_red_dst) M(bt709_luminance_or_luma_to_alpha ) M(bt709_luminance_or_luma_to_rgb) M(bilerp_clamp_8888) M(load_src ) M(store_src) M(store_src_a) M(load_dst) M(store_dst) M(scale_u8 ) M(scale_565) M(scale_1_float) M(scale_native) M( lerp_u8) M ( lerp_565) M( lerp_1_float) M(lerp_native) M(dstatop) M(dstin ) M(dstout) M(dstover) M(srcatop) M(srcin) M(srcout) M(srcover ) M(clear) M(modulate) M(multiply) M(plus_) M(screen) M(xor_) M(darken) M(difference) M(exclusion) M(hardlight) M(lighten) M(overlay) M(srcover_rgba_8888) M(matrix_translate) M(matrix_scale_translate ) M(matrix_2x3) M(matrix_perspective) M(decal_x) M(decal_y) M (decal_x_and_y) M(check_decal_mask) M(clamp_x_1) M(mirror_x_1 ) M(repeat_x_1) M(clamp_x_and_y) M(evenly_spaced_gradient) M( gradient) M(evenly_spaced_2_stop_gradient) M(xy_to_unit_angle ) M(xy_to_radius) M(emboss) M(swizzle) M(debug_x) M(debug_y) M (debug_r) M(debug_g) M(debug_b) M(debug_a) M(debug_r_255) M(debug_g_255 ) M(debug_b_255) M(debug_a_255) M(callback) M(stack_checkpoint ) M(stack_rewind) M(unbounded_set_rgb) M(unbounded_uniform_color ) M(unpremul) M(unpremul_polar) M(dither) M(load_16161616) M( load_16161616_dst) M(store_16161616) M(gather_16161616) M(load_a16 ) M(load_a16_dst) M(store_a16) M(gather_a16) M(load_r16) M(load_r16_dst ) M(store_r16) M(gather_r16) M(load_rg1616) M(load_rg1616_dst ) M(store_rg1616) M(gather_rg1616) M(load_f16) M(load_f16_dst ) M(store_f16) M(gather_f16) M(load_af16) M(load_af16_dst) M( store_af16) M(gather_af16) M(load_rf16) M(load_rf16_dst) M(store_rf16 ) M(gather_rf16) M(load_rgf16) M(load_rgf16_dst) M(store_rgf16 ) M(gather_rgf16) M(load_f32) M(load_f32_dst) M(store_f32) M( gather_f32) M(load_1010102) M(load_1010102_dst) M(store_1010102 ) M(gather_1010102) M(load_1010102_xr) M(load_1010102_xr_dst) M(store_1010102_xr) M(gather_1010102_xr) M(load_10x6) M(load_10x6_dst ) M(store_10x6) M(gather_10x6) M(gather_10101010_xr) M(load_10101010_xr ) M(load_10101010_xr_dst) M(store_10101010_xr) M(store_src_rg ) M(load_src_rg) M(byte_tables) M(colorburn) M(colordodge) M( softlight) M(hue) M(saturation) M(color) M(luminosity) M(matrix_3x3 ) M(matrix_3x4) M(matrix_4x5) M(matrix_4x3) M(parametric) M(gamma_ ) M(PQish) M(HLGish) M(HLGinvish) M(ootf) M(rgb_to_hsl) M(hsl_to_rgb ) M(css_lab_to_xyz) M(css_oklab_to_linear_srgb) M(css_oklab_gamut_map_to_linear_srgb ) M(css_hcl_to_lab) M(css_hsl_to_srgb) M(css_hwb_to_srgb) M(gauss_a_to_rgba ) M(mirror_x) M(repeat_x) M(mirror_y) M(repeat_y) M(negate_x) M(bilerp_clamp_8888_force_highp) M(bicubic_clamp_8888) M(bilinear_setup ) M(bilinear_nx) M(bilinear_px) M(bilinear_ny) M(bilinear_py) M(bicubic_setup) M(bicubic_n3x) M(bicubic_n1x) M(bicubic_p1x ) M(bicubic_p3x) M(bicubic_n3y) M(bicubic_n1y) M(bicubic_p1y) M(bicubic_p3y) M(accumulate) M(perlin_noise) M(mipmap_linear_init ) M(mipmap_linear_update) M(mipmap_linear_finish) M(xy_to_2pt_conical_strip ) M(xy_to_2pt_conical_focal_on_circle) M(xy_to_2pt_conical_well_behaved ) M(xy_to_2pt_conical_smaller) M(xy_to_2pt_conical_greater) M (alter_2pt_conical_compensate_focal) M(alter_2pt_conical_unswap ) M(mask_2pt_conical_nan) M(mask_2pt_conical_degenerates) M(apply_vector_mask ) M(set_base_pointer) M(init_lane_masks) M(store_device_xy01) M(exchange_src) M(load_condition_mask) M(store_condition_mask ) M(merge_condition_mask) M(merge_inv_condition_mask) M(load_loop_mask ) M(store_loop_mask) M(mask_off_loop_mask) M(reenable_loop_mask ) M(merge_loop_mask) M(case_op) M(continue_op) M(load_return_mask ) M(store_return_mask) M(mask_off_return_mask) M(branch_if_all_lanes_active ) M(branch_if_any_lanes_active) M(branch_if_no_lanes_active) M (branch_if_no_active_lanes_eq) M(jump) M(bitwise_and_imm_4_ints ) M(bitwise_and_imm_3_ints) M(bitwise_and_imm_2_ints) M(bitwise_and_imm_int ) M(bitwise_and_n_ints) M(bitwise_and_int) M(bitwise_and_2_ints ) M(bitwise_and_3_ints) M(bitwise_and_4_ints) M(bitwise_or_n_ints ) M(bitwise_or_int) M(bitwise_or_2_ints) M(bitwise_or_3_ints) M(bitwise_or_4_ints) M(bitwise_xor_imm_int) M(bitwise_xor_n_ints ) M(bitwise_xor_int) M(bitwise_xor_2_ints) M(bitwise_xor_3_ints ) M(bitwise_xor_4_ints) M(cast_to_float_from_int) M(cast_to_float_from_2_ints ) M(cast_to_float_from_3_ints) M(cast_to_float_from_4_ints) M (cast_to_float_from_uint) M(cast_to_float_from_2_uints) M(cast_to_float_from_3_uints ) M(cast_to_float_from_4_uints) M(cast_to_int_from_float) M(cast_to_int_from_2_floats ) M(cast_to_int_from_3_floats) M(cast_to_int_from_4_floats) M (cast_to_uint_from_float) M(cast_to_uint_from_2_floats) M(cast_to_uint_from_3_floats ) M(cast_to_uint_from_4_floats) M(abs_int) M(abs_2_ints) M(abs_3_ints ) M(abs_4_ints) M(floor_float) M(floor_2_floats) M(floor_3_floats ) M(floor_4_floats) M(ceil_float) M(ceil_2_floats) M(ceil_3_floats ) M(ceil_4_floats) M(invsqrt_float) M(invsqrt_2_floats) M(invsqrt_3_floats ) M(invsqrt_4_floats) M(inverse_mat2) M(inverse_mat3) M(inverse_mat4 ) M(sin_float) M(cos_float) M(tan_float) M(asin_float) M(acos_float ) M(atan_float) M(atan2_n_floats) M(sqrt_float) M(pow_n_floats ) M(exp_float) M(exp2_float) M(log_float) M(log2_float) M(refract_4_floats ) M(copy_uniform) M(copy_2_uniforms) M(copy_3_uniforms) M(copy_4_uniforms ) M(copy_constant) M(splat_2_constants) M(splat_3_constants) M (splat_4_constants) M(copy_slot_masked) M(copy_2_slots_masked ) M(copy_3_slots_masked) M(copy_4_slots_masked) M(copy_from_indirect_unmasked ) M(copy_from_indirect_uniform_unmasked) M(copy_to_indirect_masked ) M(swizzle_copy_to_indirect_masked) M(copy_slot_unmasked) M( copy_2_slots_unmasked) M(copy_3_slots_unmasked) M(copy_4_slots_unmasked ) M(copy_immutable_unmasked) M(copy_2_immutables_unmasked) M( copy_3_immutables_unmasked) M(copy_4_immutables_unmasked) M(swizzle_copy_slot_masked ) M(swizzle_copy_2_slots_masked) M(swizzle_copy_3_slots_masked ) M(swizzle_copy_4_slots_masked) M(swizzle_1) M(swizzle_2) M( swizzle_3) M(swizzle_4) M(shuffle) M(matrix_multiply_2) M(matrix_multiply_3 ) M(matrix_multiply_4) M(smoothstep_n_floats) M(dot_2_floats) M(dot_3_floats) M(dot_4_floats) M(add_imm_float) M(add_n_floats ) M(add_float) M(add_2_floats) M(add_3_floats) M(add_4_floats ) M(add_imm_int) M(add_n_ints) M(add_int) M(add_2_ints) M(add_3_ints ) M(add_4_ints) M(sub_n_floats) M(sub_float) M(sub_2_floats) M (sub_3_floats) M(sub_4_floats) M(sub_n_ints) M(sub_int) M(sub_2_ints ) M(sub_3_ints) M(sub_4_ints) M(mul_imm_float) M(mul_n_floats ) M(mul_float) M(mul_2_floats) M(mul_3_floats) M(mul_4_floats ) M(mul_imm_int) M(mul_n_ints) M(mul_int) M(mul_2_ints) M(mul_3_ints ) M(mul_4_ints) M(div_n_floats) M(div_float) M(div_2_floats) M (div_3_floats) M(div_4_floats) M(div_n_ints) M(div_int) M(div_2_ints ) M(div_3_ints) M(div_4_ints) M(div_n_uints) M(div_uint) M(div_2_uints ) M(div_3_uints) M(div_4_uints) M(max_imm_float) M(max_n_floats ) M(max_float) M(max_2_floats) M(max_3_floats) M(max_4_floats ) M(max_n_ints) M(max_int) M(max_2_ints) M(max_3_ints) M(max_4_ints ) M(max_n_uints) M(max_uint) M(max_2_uints) M(max_3_uints) M( max_4_uints) M(min_imm_float) M(min_n_floats) M(min_float) M( min_2_floats) M(min_3_floats) M(min_4_floats) M(min_n_ints) M (min_int) M(min_2_ints) M(min_3_ints) M(min_4_ints) M(min_n_uints ) M(min_uint) M(min_2_uints) M(min_3_uints) M(min_4_uints) M( mod_n_floats) M(mod_float) M(mod_2_floats) M(mod_3_floats) M( mod_4_floats) M(mix_n_floats) M(mix_float) M(mix_2_floats) M( mix_3_floats) M(mix_4_floats) M(mix_n_ints) M(mix_int) M(mix_2_ints ) M(mix_3_ints) M(mix_4_ints) M(cmplt_imm_float) M(cmplt_n_floats ) M(cmplt_float) M(cmplt_2_floats) M(cmplt_3_floats) M(cmplt_4_floats ) M(cmplt_imm_int) M(cmplt_n_ints) M(cmplt_int) M(cmplt_2_ints ) M(cmplt_3_ints) M(cmplt_4_ints) M(cmplt_imm_uint) M(cmplt_n_uints ) M(cmplt_uint) M(cmplt_2_uints) M(cmplt_3_uints) M(cmplt_4_uints ) M(cmple_imm_float) M(cmple_n_floats) M(cmple_float) M(cmple_2_floats ) M(cmple_3_floats) M(cmple_4_floats) M(cmple_imm_int) M(cmple_n_ints ) M(cmple_int) M(cmple_2_ints) M(cmple_3_ints) M(cmple_4_ints ) M(cmple_imm_uint) M(cmple_n_uints) M(cmple_uint) M(cmple_2_uints ) M(cmple_3_uints) M(cmple_4_uints) M(cmpeq_imm_float) M(cmpeq_n_floats ) M(cmpeq_float) M(cmpeq_2_floats) M(cmpeq_3_floats) M(cmpeq_4_floats ) M(cmpeq_imm_int) M(cmpeq_n_ints) M(cmpeq_int) M(cmpeq_2_ints ) M(cmpeq_3_ints) M(cmpeq_4_ints) M(cmpne_imm_float) M(cmpne_n_floats ) M(cmpne_float) M(cmpne_2_floats) M(cmpne_3_floats) M(cmpne_4_floats ) M(cmpne_imm_int) M(cmpne_n_ints) M(cmpne_int) M(cmpne_2_ints ) M(cmpne_3_ints) M(cmpne_4_ints) M(trace_line) M(trace_var) M (trace_enter) M(trace_exit) M(trace_scope) |
| 241 | #undef M |
| 242 | } |
| 243 | return name; |
| 244 | } |
| 245 | |
| 246 | void SkRasterPipeline::dump() const { |
| 247 | SkDebugf("SkRasterPipeline, %d stages\n", fNumStages); |
| 248 | std::vector<const char*> stages; |
| 249 | for (auto st = fStages; st; st = st->prev) { |
| 250 | stages.push_back(GetOpName(st->stage)); |
| 251 | } |
| 252 | std::reverse(stages.begin(), stages.end()); |
| 253 | for (const char* name : stages) { |
| 254 | SkDebugf("\t%s\n", name); |
| 255 | } |
| 256 | SkDebugf("\n"); |
| 257 | } |
| 258 | |
| 259 | void SkRasterPipeline::appendSetRGB(SkArenaAlloc* alloc, const float rgb[3]) { |
| 260 | auto arg = alloc->makeArrayDefault<float>(3); |
| 261 | arg[0] = rgb[0]; |
| 262 | arg[1] = rgb[1]; |
| 263 | arg[2] = rgb[2]; |
| 264 | |
| 265 | auto op = Op::unbounded_set_rgb; |
| 266 | if (0 <= rgb[0] && rgb[0] <= 1 && |
| 267 | 0 <= rgb[1] && rgb[1] <= 1 && |
| 268 | 0 <= rgb[2] && rgb[2] <= 1) |
| 269 | { |
| 270 | op = Op::set_rgb; |
| 271 | } |
| 272 | |
| 273 | this->uncheckedAppend(op, arg); |
| 274 | } |
| 275 | |
| 276 | void SkRasterPipeline::appendConstantColor(SkArenaAlloc* alloc, const float rgba[4]) { |
| 277 | // r,g,b might be outside [0,1], but alpha should probably always be in [0,1]. |
| 278 | SkASSERT(0 <= rgba[3] && rgba[3] <= 1)static_cast<void>( __builtin_expect(static_cast<bool >(0 <= rgba[3] && rgba[3] <= 1), 1) ? static_cast <void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf ("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 278, "0 <= rgba[3] && rgba[3] <= 1"); ; sk_abort_no_print (); } while (false); } } while(false); }() ); |
| 279 | |
| 280 | if (rgba[0] == 0 && rgba[1] == 0 && rgba[2] == 0 && rgba[3] == 1) { |
| 281 | this->append(Op::black_color); |
| 282 | } else if (rgba[0] == 1 && rgba[1] == 1 && rgba[2] == 1 && rgba[3] == 1) { |
| 283 | this->append(Op::white_color); |
| 284 | } else { |
| 285 | auto ctx = alloc->make<SkRasterPipelineContexts::UniformColorCtx>(); |
| 286 | skvx::float4 color = skvx::float4::Load(rgba); |
| 287 | color.store(&ctx->r); |
| 288 | |
| 289 | // uniform_color requires colors in range and can go lowp, |
| 290 | // while unbounded_uniform_color supports out-of-range colors too but not lowp. |
| 291 | if (0 <= rgba[0] && rgba[0] <= rgba[3] && |
| 292 | 0 <= rgba[1] && rgba[1] <= rgba[3] && |
| 293 | 0 <= rgba[2] && rgba[2] <= rgba[3]) { |
| 294 | // To make loads more direct, we store 8-bit values in 16-bit slots. |
| 295 | color = color * 255.0f + 0.5f; |
| 296 | ctx->rgba[0] = (uint16_t)color[0]; |
| 297 | ctx->rgba[1] = (uint16_t)color[1]; |
| 298 | ctx->rgba[2] = (uint16_t)color[2]; |
| 299 | ctx->rgba[3] = (uint16_t)color[3]; |
| 300 | this->uncheckedAppend(Op::uniform_color, ctx); |
| 301 | } else { |
| 302 | this->uncheckedAppend(Op::unbounded_uniform_color, ctx); |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | void SkRasterPipeline::appendMatrix(SkArenaAlloc* alloc, const SkMatrix& matrix) { |
| 308 | SkMatrix::TypeMask mt = matrix.getType(); |
| 309 | |
| 310 | if (mt == SkMatrix::kIdentity_Mask) { |
| 311 | return; |
| 312 | } |
| 313 | if (mt == SkMatrix::kTranslate_Mask) { |
| 314 | float* trans = alloc->makeArrayDefault<float>(2); |
| 315 | trans[0] = matrix.getTranslateX(); |
| 316 | trans[1] = matrix.getTranslateY(); |
| 317 | this->append(Op::matrix_translate, trans); |
| 318 | } else if ((mt | (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) == |
| 319 | (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { |
| 320 | float* scaleTrans = alloc->makeArrayDefault<float>(4); |
| 321 | scaleTrans[0] = matrix.getScaleX(); |
| 322 | scaleTrans[1] = matrix.getScaleY(); |
| 323 | scaleTrans[2] = matrix.getTranslateX(); |
| 324 | scaleTrans[3] = matrix.getTranslateY(); |
| 325 | this->append(Op::matrix_scale_translate, scaleTrans); |
| 326 | } else { |
| 327 | float* storage = alloc->makeArrayDefault<float>(9); |
| 328 | matrix.get9(storage); |
| 329 | if (!matrix.hasPerspective()) { |
| 330 | // note: asAffine and the 2x3 stage really only need 6 entries |
| 331 | this->append(Op::matrix_2x3, storage); |
| 332 | } else { |
| 333 | this->append(Op::matrix_perspective, storage); |
| 334 | } |
| 335 | } |
| 336 | } |
| 337 | |
| 338 | void SkRasterPipeline::appendLoad(SkColorType ct, const SkRasterPipelineContexts::MemoryCtx* ctx) { |
| 339 | switch (ct) { |
| 340 | case kUnknown_SkColorType: SkASSERT(false)static_cast<void>( __builtin_expect(static_cast<bool >(false), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled ()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n" , "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp", 340 , "false"); ; sk_abort_no_print(); } while (false); } } while (false); }() ); break; |
| 341 | |
| 342 | case kAlpha_8_SkColorType: this->append(Op::load_a8, ctx); break; |
| 343 | case kA16_unorm_SkColorType: this->append(Op::load_a16, ctx); break; |
| 344 | case kA16_float_SkColorType: this->append(Op::load_af16, ctx); break; |
| 345 | case kRGB_565_SkColorType: this->append(Op::load_565, ctx); break; |
| 346 | case kARGB_4444_SkColorType: this->append(Op::load_4444, ctx); break; |
| 347 | case kR8G8_unorm_SkColorType: this->append(Op::load_rg88, ctx); break; |
| 348 | case kR16_unorm_SkColorType: this->append(Op::load_r16, ctx); break; |
| 349 | case kR16_float_SkColorType: this->append(Op::load_rf16, ctx); break; |
| 350 | case kR16G16_unorm_SkColorType: this->append(Op::load_rg1616, ctx); break; |
| 351 | case kR16G16_float_SkColorType: this->append(Op::load_rgf16, ctx); break; |
| 352 | case kRGBA_8888_SkColorType: this->append(Op::load_8888, ctx); break; |
| 353 | case kRGBA_1010102_SkColorType: this->append(Op::load_1010102, ctx); break; |
| 354 | case kR16G16B16A16_unorm_SkColorType:this->append(Op::load_16161616,ctx); break; |
| 355 | case kRGBA_F16Norm_SkColorType: |
| 356 | case kRGBA_F16_SkColorType: this->append(Op::load_f16, ctx); break; |
| 357 | case kRGBA_F32_SkColorType: this->append(Op::load_f32, ctx); break; |
| 358 | case kRGBA_10x6_SkColorType: this->append(Op::load_10x6, ctx); break; |
| 359 | |
| 360 | case kGray_8_SkColorType: this->append(Op::load_a8, ctx); |
| 361 | this->append(Op::alpha_to_gray); |
| 362 | break; |
| 363 | |
| 364 | case kR8_unorm_SkColorType: this->append(Op::load_a8, ctx); |
| 365 | this->append(Op::alpha_to_red); |
| 366 | break; |
| 367 | |
| 368 | case kRGB_888x_SkColorType: this->append(Op::load_8888, ctx); |
| 369 | this->append(Op::force_opaque); |
| 370 | break; |
| 371 | |
| 372 | case kBGRA_1010102_SkColorType: this->append(Op::load_1010102, ctx); |
| 373 | this->append(Op::swap_rb); |
| 374 | break; |
| 375 | |
| 376 | case kRGB_101010x_SkColorType: this->append(Op::load_1010102, ctx); |
| 377 | this->append(Op::force_opaque); |
| 378 | break; |
| 379 | |
| 380 | case kBGR_101010x_SkColorType: this->append(Op::load_1010102, ctx); |
| 381 | this->append(Op::force_opaque); |
| 382 | this->append(Op::swap_rb); |
| 383 | break; |
| 384 | |
| 385 | case kBGRA_10101010_XR_SkColorType: this->append(Op::load_10101010_xr, ctx); |
| 386 | this->append(Op::swap_rb); |
| 387 | break; |
| 388 | |
| 389 | case kBGR_101010x_XR_SkColorType: this->append(Op::load_1010102_xr, ctx); |
| 390 | this->append(Op::force_opaque); |
| 391 | this->append(Op::swap_rb); |
| 392 | break; |
| 393 | case kRGB_F16F16F16x_SkColorType: this->append(Op::load_f16, ctx); |
| 394 | this->append(Op::force_opaque); |
| 395 | break; |
| 396 | |
| 397 | case kBGRA_8888_SkColorType: this->append(Op::load_8888, ctx); |
| 398 | this->append(Op::swap_rb); |
| 399 | break; |
| 400 | |
| 401 | case kSRGBA_8888_SkColorType: |
| 402 | this->append(Op::load_8888, ctx); |
| 403 | this->appendTransferFunction(*skcms_sRGB_TransferFunction()); |
| 404 | break; |
| 405 | } |
| 406 | } |
| 407 | |
| 408 | void SkRasterPipeline::appendLoadDst(SkColorType ct, |
| 409 | const SkRasterPipelineContexts::MemoryCtx* ctx) { |
| 410 | switch (ct) { |
| 411 | case kUnknown_SkColorType: SkASSERT(false)static_cast<void>( __builtin_expect(static_cast<bool >(false), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled ()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n" , "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp", 411 , "false"); ; sk_abort_no_print(); } while (false); } } while (false); }() ); break; |
| 412 | |
| 413 | case kAlpha_8_SkColorType: this->append(Op::load_a8_dst, ctx); break; |
| 414 | case kA16_unorm_SkColorType: this->append(Op::load_a16_dst, ctx); break; |
| 415 | case kA16_float_SkColorType: this->append(Op::load_af16_dst, ctx); break; |
| 416 | case kRGB_565_SkColorType: this->append(Op::load_565_dst, ctx); break; |
| 417 | case kARGB_4444_SkColorType: this->append(Op::load_4444_dst, ctx); break; |
| 418 | case kR8G8_unorm_SkColorType: this->append(Op::load_rg88_dst, ctx); break; |
| 419 | case kR16_unorm_SkColorType: this->append(Op::load_r16_dst, ctx); break; |
| 420 | case kR16_float_SkColorType: this->append(Op::load_rf16_dst, ctx); break; |
| 421 | case kR16G16_unorm_SkColorType: this->append(Op::load_rg1616_dst, ctx); break; |
| 422 | case kR16G16_float_SkColorType: this->append(Op::load_rgf16_dst, ctx); break; |
| 423 | case kRGBA_8888_SkColorType: this->append(Op::load_8888_dst, ctx); break; |
| 424 | case kRGBA_1010102_SkColorType: this->append(Op::load_1010102_dst, ctx); break; |
| 425 | case kR16G16B16A16_unorm_SkColorType: this->append(Op::load_16161616_dst,ctx); break; |
| 426 | case kRGBA_F16Norm_SkColorType: |
| 427 | case kRGBA_F16_SkColorType: this->append(Op::load_f16_dst, ctx); break; |
| 428 | case kRGBA_F32_SkColorType: this->append(Op::load_f32_dst, ctx); break; |
| 429 | case kRGBA_10x6_SkColorType: this->append(Op::load_10x6_dst, ctx); break; |
| 430 | |
| 431 | case kGray_8_SkColorType: this->append(Op::load_a8_dst, ctx); |
| 432 | this->append(Op::alpha_to_gray_dst); |
| 433 | break; |
| 434 | |
| 435 | case kR8_unorm_SkColorType: this->append(Op::load_a8_dst, ctx); |
| 436 | this->append(Op::alpha_to_red_dst); |
| 437 | break; |
| 438 | |
| 439 | case kRGB_888x_SkColorType: this->append(Op::load_8888_dst, ctx); |
| 440 | this->append(Op::force_opaque_dst); |
| 441 | break; |
| 442 | |
| 443 | case kBGRA_1010102_SkColorType: this->append(Op::load_1010102_dst, ctx); |
| 444 | this->append(Op::swap_rb_dst); |
| 445 | break; |
| 446 | |
| 447 | case kRGB_101010x_SkColorType: this->append(Op::load_1010102_dst, ctx); |
| 448 | this->append(Op::force_opaque_dst); |
| 449 | break; |
| 450 | |
| 451 | case kBGR_101010x_SkColorType: this->append(Op::load_1010102_dst, ctx); |
| 452 | this->append(Op::force_opaque_dst); |
| 453 | this->append(Op::swap_rb_dst); |
| 454 | break; |
| 455 | |
| 456 | case kBGR_101010x_XR_SkColorType: this->append(Op::load_1010102_xr_dst, ctx); |
| 457 | this->append(Op::force_opaque_dst); |
| 458 | this->append(Op::swap_rb_dst); |
| 459 | break; |
| 460 | |
| 461 | case kBGRA_10101010_XR_SkColorType: this->append(Op::load_10101010_xr_dst, ctx); |
| 462 | this->append(Op::swap_rb_dst); |
| 463 | break; |
| 464 | case kRGB_F16F16F16x_SkColorType: this->append(Op::load_f16_dst, ctx); |
| 465 | this->append(Op::force_opaque_dst); |
| 466 | break; |
| 467 | |
| 468 | case kBGRA_8888_SkColorType: this->append(Op::load_8888_dst, ctx); |
| 469 | this->append(Op::swap_rb_dst); |
| 470 | break; |
| 471 | |
| 472 | case kSRGBA_8888_SkColorType: |
| 473 | // TODO: We could remove the double-swap if we had _dst versions of all the TF stages |
| 474 | this->append(Op::load_8888_dst, ctx); |
| 475 | this->append(Op::swap_src_dst); |
| 476 | this->appendTransferFunction(*skcms_sRGB_TransferFunction()); |
| 477 | this->append(Op::swap_src_dst); |
| 478 | break; |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | void SkRasterPipeline::appendStore(SkColorType ct, const SkRasterPipelineContexts::MemoryCtx* ctx) { |
| 483 | switch (ct) { |
| 484 | case kUnknown_SkColorType: SkASSERT(false)static_cast<void>( __builtin_expect(static_cast<bool >(false), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled ()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n" , "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp", 484 , "false"); ; sk_abort_no_print(); } while (false); } } while (false); }() ); break; |
| 485 | |
| 486 | case kAlpha_8_SkColorType: this->append(Op::store_a8, ctx); break; |
| 487 | case kR8_unorm_SkColorType: this->append(Op::store_r8, ctx); break; |
| 488 | case kA16_unorm_SkColorType: this->append(Op::store_a16, ctx); break; |
| 489 | case kA16_float_SkColorType: this->append(Op::store_af16, ctx); break; |
| 490 | case kRGB_565_SkColorType: this->append(Op::store_565, ctx); break; |
| 491 | case kARGB_4444_SkColorType: this->append(Op::store_4444, ctx); break; |
| 492 | case kR8G8_unorm_SkColorType: this->append(Op::store_rg88, ctx); break; |
| 493 | case kR16_unorm_SkColorType: this->append(Op::store_r16, ctx); break; |
| 494 | case kR16_float_SkColorType: this->append(Op::store_rf16, ctx); break; |
| 495 | case kR16G16_unorm_SkColorType: this->append(Op::store_rg1616, ctx); break; |
| 496 | case kR16G16_float_SkColorType: this->append(Op::store_rgf16, ctx); break; |
| 497 | case kRGBA_8888_SkColorType: this->append(Op::store_8888, ctx); break; |
| 498 | case kRGBA_1010102_SkColorType: this->append(Op::store_1010102, ctx); break; |
| 499 | case kR16G16B16A16_unorm_SkColorType: this->append(Op::store_16161616,ctx); break; |
| 500 | case kRGBA_F16Norm_SkColorType: |
| 501 | case kRGBA_F16_SkColorType: this->append(Op::store_f16, ctx); break; |
| 502 | case kRGBA_F32_SkColorType: this->append(Op::store_f32, ctx); break; |
| 503 | case kRGBA_10x6_SkColorType: this->append(Op::store_10x6, ctx); break; |
| 504 | |
| 505 | case kRGB_888x_SkColorType: this->append(Op::force_opaque); |
| 506 | this->append(Op::store_8888, ctx); |
| 507 | break; |
| 508 | |
| 509 | case kBGRA_1010102_SkColorType: this->append(Op::swap_rb); |
| 510 | this->append(Op::store_1010102, ctx); |
| 511 | break; |
| 512 | |
| 513 | case kRGB_101010x_SkColorType: this->append(Op::force_opaque); |
| 514 | this->append(Op::store_1010102, ctx); |
| 515 | break; |
| 516 | |
| 517 | case kBGR_101010x_SkColorType: this->append(Op::force_opaque); |
| 518 | this->append(Op::swap_rb); |
| 519 | this->append(Op::store_1010102, ctx); |
| 520 | break; |
| 521 | |
| 522 | case kBGR_101010x_XR_SkColorType: this->append(Op::force_opaque); |
| 523 | this->append(Op::swap_rb); |
| 524 | this->append(Op::store_1010102_xr, ctx); |
| 525 | break; |
| 526 | case kRGB_F16F16F16x_SkColorType: this->append(Op::force_opaque); |
| 527 | this->append(Op::store_f16, ctx); |
| 528 | break; |
| 529 | |
| 530 | case kBGRA_10101010_XR_SkColorType: this->append(Op::swap_rb); |
| 531 | this->append(Op::store_10101010_xr, ctx); |
| 532 | break; |
| 533 | |
| 534 | case kGray_8_SkColorType: this->append(Op::bt709_luminance_or_luma_to_alpha); |
| 535 | this->append(Op::store_a8, ctx); |
| 536 | break; |
| 537 | |
| 538 | case kBGRA_8888_SkColorType: this->append(Op::swap_rb); |
| 539 | this->append(Op::store_8888, ctx); |
| 540 | break; |
| 541 | |
| 542 | case kSRGBA_8888_SkColorType: |
| 543 | this->appendTransferFunction(*skcms_sRGB_Inverse_TransferFunction()); |
| 544 | this->append(Op::store_8888, ctx); |
| 545 | break; |
| 546 | } |
| 547 | } |
| 548 | |
| 549 | void SkRasterPipeline::appendTransferFunction(const skcms_TransferFunction& tf) { |
| 550 | void* ctx = const_cast<void*>(static_cast<const void*>(&tf)); |
| 551 | switch (skcms_TransferFunction_getType(&tf)) { |
| 552 | default: SkASSERT(false)static_cast<void>( __builtin_expect(static_cast<bool >(false), 1) ? static_cast<void>(0) : []{ do { if (sk_abort_is_enabled ()) { do { SkDebugf("%s:%d" ": fatal error: \"" "check(%s)" "\"\n" , "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp", 552 , "false"); ; sk_abort_no_print(); } while (false); } } while (false); }() ); break; |
| 553 | |
| 554 | case skcms_TFType_sRGBish: |
| 555 | if (tf.a == 1 && tf.b == 0 && tf.c == 0 && tf.d == 0 && tf.e == 0 && tf.f == 0) { |
| 556 | this->uncheckedAppend(Op::gamma_, ctx); |
| 557 | } else { |
| 558 | this->uncheckedAppend(Op::parametric, ctx); |
| 559 | } |
| 560 | break; |
| 561 | case skcms_TFType_PQish: this->uncheckedAppend(Op::PQish, ctx); break; |
| 562 | case skcms_TFType_HLGish: this->uncheckedAppend(Op::HLGish, ctx); break; |
| 563 | case skcms_TFType_HLGinvish: this->uncheckedAppend(Op::HLGinvish, ctx); break; |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | // GPUs clamp all color channels to the limits of the format just before the blend step. To match |
| 568 | // that auto-clamp, the RP blitter uses this helper immediately before appending blending stages. |
| 569 | void SkRasterPipeline::appendClampIfNormalized(const SkImageInfo& info) { |
| 570 | if (SkColorTypeIsNormalized(info.colorType())) { |
| 571 | this->uncheckedAppend(Op::clamp_01, nullptr); |
| 572 | } |
| 573 | } |
| 574 | |
| 575 | void SkRasterPipeline::appendStackRewind() { |
| 576 | if (!fRewindCtx) { |
| 577 | fRewindCtx = fAlloc->make<SkRasterPipelineContexts::RewindCtx>(); |
| 578 | } |
| 579 | this->uncheckedAppend(Op::stack_rewind, fRewindCtx); |
| 580 | } |
| 581 | |
| 582 | static void prepend_to_pipeline(SkRasterPipelineStage*& ip, SkOpts::StageFn stageFn, void* ctx) { |
| 583 | --ip; |
| 584 | ip->fn = stageFn; |
| 585 | ip->ctx = ctx; |
| 586 | } |
| 587 | |
| 588 | bool SkRasterPipeline::buildLowpPipeline(SkRasterPipelineStage* ip) const { |
| 589 | if (gForceHighPrecisionRasterPipeline || fRewindCtx) { |
| 590 | return false; |
| 591 | } |
| 592 | // Stages are stored backwards in fStages; to compensate, we assemble the pipeline in reverse |
| 593 | // here, back to front. |
| 594 | prepend_to_pipeline(ip, SkOpts::just_return_lowp, /*ctx=*/nullptr); |
| 595 | for (const StageList* st = fStages; st; st = st->prev) { |
| 596 | int opIndex = (int)st->stage; |
| 597 | if (opIndex >= kNumRasterPipelineLowpOps || !SkOpts::ops_lowp[opIndex]) { |
| 598 | // This program contains a stage that doesn't exist in lowp. |
| 599 | return false; |
| 600 | } |
| 601 | prepend_to_pipeline(ip, SkOpts::ops_lowp[opIndex], st->ctx); |
| 602 | } |
| 603 | return true; |
| 604 | } |
| 605 | |
| 606 | void SkRasterPipeline::buildHighpPipeline(SkRasterPipelineStage* ip) const { |
| 607 | // We assemble the pipeline in reverse, since the stage list is stored backwards. |
| 608 | prepend_to_pipeline(ip, SkOpts::just_return_highp, /*ctx=*/nullptr); |
| 609 | for (const StageList* st = fStages; st; st = st->prev) { |
| 610 | int opIndex = (int)st->stage; |
| 611 | prepend_to_pipeline(ip, SkOpts::ops_highp[opIndex], st->ctx); |
| 612 | } |
| 613 | |
| 614 | // stack_checkpoint and stack_rewind are only implemented in highp. We only need these stages |
| 615 | // when generating long (or looping) pipelines from SkSL. The other stages used by the SkSL |
| 616 | // Raster Pipeline generator will only have highp implementations, because we can't execute SkSL |
| 617 | // code without floating point. |
| 618 | if (fRewindCtx) { |
| 619 | const int rewindIndex = (int)Op::stack_checkpoint; |
| 620 | prepend_to_pipeline(ip, SkOpts::ops_highp[rewindIndex], fRewindCtx); |
| 621 | } |
| 622 | } |
| 623 | |
| 624 | SkRasterPipeline::StartPipelineFn SkRasterPipeline::buildPipeline(SkRasterPipelineStage* ip) const { |
| 625 | // We try to build a lowp pipeline first; if that fails, we fall back to a highp float pipeline. |
| 626 | if (this->buildLowpPipeline(ip)) { |
| 627 | return SkOpts::start_pipeline_lowp; |
| 628 | } |
| 629 | |
| 630 | this->buildHighpPipeline(ip); |
| 631 | return SkOpts::start_pipeline_highp; |
| 632 | } |
| 633 | |
| 634 | int SkRasterPipeline::stagesNeeded() const { |
| 635 | // Add 1 to budget for a `just_return` stage at the end. |
| 636 | int stages = fNumStages + 1; |
| 637 | |
| 638 | // If we have any stack_rewind stages, we will need to inject a stack_checkpoint stage. |
| 639 | if (fRewindCtx) { |
| 640 | stages += 1; |
| 641 | } |
| 642 | return stages; |
| 643 | } |
| 644 | |
| 645 | void SkRasterPipeline::run(size_t x, size_t y, size_t w, size_t h) const { |
| 646 | if (this->empty()) { |
| 647 | return; |
| 648 | } |
| 649 | |
| 650 | int stagesNeeded = this->stagesNeeded(); |
| 651 | |
| 652 | // Best to not use fAlloc here... we can't bound how often run() will be called. |
| 653 | AutoSTMalloc<32, SkRasterPipelineStage> program(stagesNeeded); |
| 654 | |
| 655 | size_t numMemoryCtxs = fMemoryCtxInfos.size(); |
| 656 | AutoSTMalloc<2, SkRasterPipelineContexts::MemoryCtxPatch> patches(numMemoryCtxs); |
| 657 | for (size_t i = 0; i < numMemoryCtxs; ++i) { |
| 658 | patches[i].info = fMemoryCtxInfos[i]; |
| 659 | patches[i].backup = nullptr; |
| 660 | memset(patches[i].scratch, 0, sizeof(patches[i].scratch)); |
| 661 | } |
| 662 | |
| 663 | auto start_pipeline = this->buildPipeline(program.get() + stagesNeeded); |
| 664 | start_pipeline(x, y, x + w, y + h, program.get(), |
| 665 | SkSpan{patches.data(), numMemoryCtxs}, |
| 666 | fTailPointer); |
| 667 | } |
| 668 | |
| 669 | std::function<void(size_t, size_t, size_t, size_t)> SkRasterPipeline::compile() const { |
| 670 | if (this->empty()) { |
| 671 | return [](size_t, size_t, size_t, size_t) {}; |
| 672 | } |
| 673 | |
| 674 | int stagesNeeded = this->stagesNeeded(); |
| 675 | |
| 676 | SkRasterPipelineStage* program = fAlloc->makeArray<SkRasterPipelineStage>(stagesNeeded); |
| 677 | |
| 678 | size_t numMemoryCtxs = fMemoryCtxInfos.size(); |
| 679 | SkRasterPipelineContexts::MemoryCtxPatch* patches = |
| 680 | fAlloc->makeArray<SkRasterPipelineContexts::MemoryCtxPatch>(numMemoryCtxs); |
| 681 | for (size_t i = 0; i < numMemoryCtxs; ++i) { |
| 682 | patches[i].info = fMemoryCtxInfos[i]; |
| 683 | patches[i].backup = nullptr; |
| 684 | memset(patches[i].scratch, 0, sizeof(patches[i].scratch)); |
| 685 | } |
| 686 | uint8_t* tailPointer = fTailPointer; |
| 687 | |
| 688 | auto start_pipeline = this->buildPipeline(program + stagesNeeded); |
| 689 | return [=](size_t x, size_t y, size_t w, size_t h) { |
| 690 | start_pipeline(x, y, x + w, y + h, program, |
| 691 | {patches, numMemoryCtxs}, |
| 692 | tailPointer); |
| 693 | }; |
| 694 | } |
| 695 | |
| 696 | void SkRasterPipeline::addMemoryContext(SkRasterPipelineContexts::MemoryCtx* ctx, |
| 697 | int bytesPerPixel, |
| 698 | bool load, |
| 699 | bool store) { |
| 700 | SkRasterPipelineContexts::MemoryCtxInfo* info = std::find_if( |
| 701 | fMemoryCtxInfos.begin(), |
| 702 | fMemoryCtxInfos.end(), |
| 703 | [=](const SkRasterPipelineContexts::MemoryCtxInfo& i) { return i.context == ctx; }); |
| 704 | if (info != fMemoryCtxInfos.end()) { |
| 705 | SkASSERT(bytesPerPixel == info->bytesPerPixel)static_cast<void>( __builtin_expect(static_cast<bool >(bytesPerPixel == info->bytesPerPixel), 1) ? static_cast <void>(0) : []{ do { if (sk_abort_is_enabled()) { do { SkDebugf ("%s:%d" ": fatal error: \"" "check(%s)" "\"\n", "./../../../gfx/skia/skia/src/core/SkRasterPipeline.cpp" , 705, "bytesPerPixel == info->bytesPerPixel"); ; sk_abort_no_print (); } while (false); } } while(false); }() ); |
| 706 | info->load = info->load || load; |
| 707 | info->store = info->store || store; |
| 708 | } else { |
| 709 | fMemoryCtxInfos.push_back( |
| 710 | SkRasterPipelineContexts::MemoryCtxInfo{ctx, bytesPerPixel, load, store}); |
| 711 | } |
| 712 | } |