1281b33fdd909ee3f43192cdf950ce00e3df62407mtklein/* 2281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * Copyright 2016 Google Inc. 3281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * 4281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * Use of this source code is governed by a BSD-style license that can be 5281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * found in the LICENSE file. 6281b33fdd909ee3f43192cdf950ce00e3df62407mtklein */ 7281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 8281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#ifndef SkRasterPipeline_DEFINED 9281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#define SkRasterPipeline_DEFINED 10281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 110a76b413eac46ec218b367c5456709059557f5dbMike Klein#include "SkArenaAlloc.h" 12d37d5d96493604c12cfaa2d64bcbd32c41b01f3bMike Klein#include "SkImageInfo.h" 13281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#include "SkNx.h" 14281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#include "SkTArray.h" 15281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#include "SkTypes.h" 160a76b413eac46ec218b367c5456709059557f5dbMike Klein#include <functional> 17cc63173634e773eac5de0b92f05d117ed2bdca84Mike Klein#include <vector> 18281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 19bba02c203190a19bce7eb60887c4ae64041c8ae8Mike Kleinstruct SkJumper_constants; 203b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Kleinstruct SkJumper_Engine; 21c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reedstruct SkPM4f; 22b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 23281b33fdd909ee3f43192cdf950ce00e3df62407mtklein/** 24281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * SkRasterPipeline provides a cheap way to chain together a pixel processing pipeline. 25281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * 26281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * It's particularly designed for situations where the potential pipeline is extremely 27281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * combinatoric: {N dst formats} x {M source formats} x {K mask formats} x {C transfer modes} ... 28281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * No one wants to write specialized routines for all those combinations, and if we did, we'd 29281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * end up bloating our code size dramatically. SkRasterPipeline stages can be chained together 30281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * at runtime, so we can scale this problem linearly rather than combinatorically. 31281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * 32b8d88d72cbe9cc3dde91eaf58e928b34748526a7Mike Klein * Each stage is represented by a function conforming to a common interface and by an 33b8d88d72cbe9cc3dde91eaf58e928b34748526a7Mike Klein * arbitrary context pointer. The stage funciton arguments and calling convention are 34b8d88d72cbe9cc3dde91eaf58e928b34748526a7Mike Klein * designed to maximize the amount of data we can pass along the pipeline cheaply, and 35b8d88d72cbe9cc3dde91eaf58e928b34748526a7Mike Klein * vary depending on CPU feature detection. 36281b33fdd909ee3f43192cdf950ce00e3df62407mtklein * 37b8d88d72cbe9cc3dde91eaf58e928b34748526a7Mike Klein * If you'd like to see how this works internally, you want to start digging around src/jumper. 38281b33fdd909ee3f43192cdf950ce00e3df62407mtklein */ 39281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 401f49f26353997195030aeab41c8665e1860d2958Mike Klein#define SK_RASTER_PIPELINE_STAGES(M) \ 417fee90cb5eda2345bb8ec9be706aea1a09866005Mike Klein M(callback) \ 429f2b3d1fbfa16146184a13b778fbe2fa5355c51bMike Klein M(move_src_dst) M(move_dst_src) \ 43279091ef85eec98969b72805bbf613f1c0660380Mike Reed M(clamp_0) M(clamp_1) M(clamp_a) M(clamp_a_dst) \ 44883c9bce671fb955574a6c0e46f57f57189bd6c6Mike Reed M(unpremul) M(premul) M(premul_dst) \ 45111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(set_rgb) M(swap_rb) \ 46279091ef85eec98969b72805bbf613f1c0660380Mike Reed M(from_srgb) M(from_srgb_dst) M(to_srgb) \ 47c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed M(black_color) M(white_color) M(uniform_color) \ 48c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed M(seed_shader) M(dither) \ 49111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_a8) M(load_a8_dst) M(store_a8) M(gather_a8) \ 50111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_g8) M(load_g8_dst) M(gather_g8) \ 51111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_565) M(load_565_dst) M(store_565) M(gather_565) \ 52111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_4444) M(load_4444_dst) M(store_4444) M(gather_4444) \ 53111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_f16) M(load_f16_dst) M(store_f16) M(gather_f16) \ 54279091ef85eec98969b72805bbf613f1c0660380Mike Reed M(load_f32) M(load_f32_dst) M(store_f32) \ 55111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_8888) M(load_8888_dst) M(store_8888) M(gather_8888) \ 56111f8a9eea6980a70a300e3a8bfd758257310fe2Mike Klein M(load_bgra) M(load_bgra_dst) M(store_bgra) M(gather_bgra) \ 571da27ef853ae3e701b7f4aae670c21684396dcceMatt Sarett M(load_u16_be) M(load_rgb_u16_be) M(store_u16_be) \ 585bee0b6de6b3ad1166d067e6b5046b48b8240a29Matt Sarett M(load_tables_u16_be) M(load_tables_rgb_u16_be) \ 599959f723c33d609519c265abb5c4f48cba71fd6fMike Reed M(load_tables) M(load_rgba) M(store_rgba) \ 60babd93e11290067da65567ea02f556c251a67c71Mike Klein M(scale_u8) M(scale_1_float) \ 61babd93e11290067da65567ea02f556c251a67c71Mike Klein M(lerp_u8) M(lerp_565) M(lerp_1_float) \ 621f49f26353997195030aeab41c8665e1860d2958Mike Klein M(dstatop) M(dstin) M(dstout) M(dstover) \ 631f49f26353997195030aeab41c8665e1860d2958Mike Klein M(srcatop) M(srcin) M(srcout) M(srcover) \ 641f49f26353997195030aeab41c8665e1860d2958Mike Klein M(clear) M(modulate) M(multiply) M(plus_) M(screen) M(xor_) \ 651f49f26353997195030aeab41c8665e1860d2958Mike Klein M(colorburn) M(colordodge) M(darken) M(difference) \ 661f49f26353997195030aeab41c8665e1860d2958Mike Klein M(exclusion) M(hardlight) M(lighten) M(overlay) M(softlight) \ 67bb33833ed25c30007e4ea3cd3de6df728407f94eMike Klein M(hue) M(saturation) M(color) M(luminosity) \ 68506262665c9b02514dea9a4da3211a00fdf02dbeMike Klein M(srcover_rgba_8888) \ 6906a65e2799eaead18f778792801406aff4aec0d9Mike Klein M(luminance_to_alpha) \ 707aad8cc2ff7a580bd5852d57289ace8c8dced6f5Mike Reed M(matrix_translate) M(matrix_scale_translate) \ 710264095cfd1aa205b0af218c7e5abbaff8a5db0cMike Reed M(matrix_2x3) M(matrix_3x4) M(matrix_4x5) M(matrix_4x3) \ 72c01e7dff5fa013832b808f72ac74d81eaa1cb145Mike Klein M(matrix_perspective) \ 73cfcf624c39683a8364fa7f22235b787a23675780Mike Klein M(parametric_r) M(parametric_g) M(parametric_b) \ 745476128f0a88217414f05e6a7ee518cdb411d026raftias M(parametric_a) \ 755476128f0a88217414f05e6a7ee518cdb411d026raftias M(table_r) M(table_g) M(table_b) M(table_a) \ 76c17dc24fa9994eacc640d3adc6633a02fd96d3fcMike Klein M(lab_to_xyz) \ 779f85d68887a61f93656dbfacdd3f978d510c02eeMike Klein M(clamp_x) M(mirror_x) M(repeat_x) \ 789f85d68887a61f93656dbfacdd3f978d510c02eeMike Klein M(clamp_y) M(mirror_y) M(repeat_y) \ 799f85d68887a61f93656dbfacdd3f978d510c02eeMike Klein M(clamp_x_1) M(mirror_x_1) M(repeat_x_1) \ 80b0b17d1e5375a65b8956a8990d63e0d02357fdafMike Klein M(bilinear_nx) M(bilinear_px) M(bilinear_ny) M(bilinear_py) \ 81b0b17d1e5375a65b8956a8990d63e0d02357fdafMike Klein M(bicubic_n3x) M(bicubic_n1x) M(bicubic_p1x) M(bicubic_p3x) \ 82b0b17d1e5375a65b8956a8990d63e0d02357fdafMike Klein M(bicubic_n3y) M(bicubic_n1y) M(bicubic_p1y) M(bicubic_p3y) \ 83c86e470c190934a2f7680ed10cf9fad757e1ab75Florin Malita M(save_xy) M(accumulate) \ 844de1304297d7220b223c829bf386f97815db1654Herb Derby M(evenly_spaced_gradient) \ 856533159f2c83d0af51f79c3d85461580e2346080Mike Reed M(gauss_a_to_rgba) M(gradient) \ 865c7960be57010bf61db3d4ce879a3194687b5af9Mike Klein M(evenly_spaced_2_stop_gradient) \ 875c7960be57010bf61db3d4ce879a3194687b5af9Mike Klein M(xy_to_unit_angle) \ 88090fbf86cf90dd326b3b3b59cde0a46b63a594a6Herb Derby M(xy_to_radius) \ 899026fe13a751582e58e98f9bf735c18b4719d7feFlorin Malita M(xy_to_2pt_conical_quadratic_min) \ 909026fe13a751582e58e98f9bf735c18b4719d7feFlorin Malita M(xy_to_2pt_conical_quadratic_max) \ 919026fe13a751582e58e98f9bf735c18b4719d7feFlorin Malita M(xy_to_2pt_conical_linear) \ 929026fe13a751582e58e98f9bf735c18b4719d7feFlorin Malita M(mask_2pt_conical_degenerates) M(apply_vector_mask) \ 93e522f4c455d0d5dbe813f38d16c0d4cd46fa5deeMatt Sarett M(byte_tables) M(byte_tables_rgb) \ 943b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein M(rgb_to_hsl) M(hsl_to_rgb) \ 953b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein M(store_8888_2d) 96aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868Mike Klein 97281b33fdd909ee3f43192cdf950ce00e3df62407mtkleinclass SkRasterPipeline { 98281b33fdd909ee3f43192cdf950ce00e3df62407mtkleinpublic: 99b24704d35f67f5b460be9c92794892e06adceb46Mike Klein explicit SkRasterPipeline(SkArenaAlloc*); 100b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 101b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline(const SkRasterPipeline&) = delete; 102b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline(SkRasterPipeline&&) = default; 103b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 104b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline& operator=(const SkRasterPipeline&) = delete; 105b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline& operator=(SkRasterPipeline&&) = default; 106b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 107b24704d35f67f5b460be9c92794892e06adceb46Mike Klein void reset(); 108281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 109fa9f241a85c55c32a3fe2ae0324811de998f7a2eMike Klein enum StockStage { 110aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868Mike Klein #define M(stage) stage, 111aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868Mike Klein SK_RASTER_PIPELINE_STAGES(M) 112aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868Mike Klein #undef M 113fa9f241a85c55c32a3fe2ae0324811de998f7a2eMike Klein }; 11426bea5d55735367152378bae14453e9666d1c625Mike Klein void append(StockStage, void* = nullptr); 11526bea5d55735367152378bae14453e9666d1c625Mike Klein void append(StockStage stage, const void* ctx) { this->append(stage, const_cast<void*>(ctx)); } 116fa9f241a85c55c32a3fe2ae0324811de998f7a2eMike Klein 1179a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein // Append all stages to this pipeline. 1189a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein void extend(const SkRasterPipeline&); 1199a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein 120319ba3d3a177498095c31696e0aec8b3af25f663Mike Klein // Runs the pipeline walking x through [x,x+n). 121761d27c4d76bbd553c10cfe835d572b6fa33cf26Mike Klein void run(size_t x, size_t y, size_t n) const; 122c789b61167dd98efc3c3bfcf9673eef24c2e57f4Mike Klein 1233b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein // Runs the pipeline in 2d from (x,y) inclusive to (x+w,y+h) exclusive. 1243b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein void run_2d(size_t x, size_t y, size_t w, size_t h) const; 1253b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein 1260a76b413eac46ec218b367c5456709059557f5dbMike Klein // Allocates a thunk which amortizes run() setup cost in alloc. 127761d27c4d76bbd553c10cfe835d572b6fa33cf26Mike Klein std::function<void(size_t, size_t, size_t)> compile() const; 1280a76b413eac46ec218b367c5456709059557f5dbMike Klein 1293928c6b6165cf2d13d3b5f50762d7f621706a946Mike Klein void dump() const; 1303928c6b6165cf2d13d3b5f50762d7f621706a946Mike Klein 131d37d5d96493604c12cfaa2d64bcbd32c41b01f3bMike Klein // Conversion from sRGB can be subtly tricky when premultiplication is involved. 132d37d5d96493604c12cfaa2d64bcbd32c41b01f3bMike Klein // Use these helpers to keep things sane. 1338c8cb5bfc547229422a33db5c344fe1542bf00a7Mike Klein void append_from_srgb(SkAlphaType); 134279091ef85eec98969b72805bbf613f1c0660380Mike Reed void append_from_srgb_dst(SkAlphaType); 135d37d5d96493604c12cfaa2d64bcbd32c41b01f3bMike Klein 1366b59bf424c9d9d8a72d3c002871f143e6aff623eMike Reed // Appends a stage for the specified matrix. Tries to optimize the stage by analyzing 1376b59bf424c9d9d8a72d3c002871f143e6aff623eMike Reed // the type of matrix. 1386b59bf424c9d9d8a72d3c002871f143e6aff623eMike Reed void append_matrix(SkArenaAlloc*, const SkMatrix&); 1396b59bf424c9d9d8a72d3c002871f143e6aff623eMike Reed 140c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed // Appends a stage for the uniform color. Tries to optimize the stage based on the color. 141c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed void append_uniform_color(SkArenaAlloc*, const SkPM4f& color); 142c91e3877a57ef140b688627b8c0acaafbefc9034Mike Reed 143b24704d35f67f5b460be9c92794892e06adceb46Mike Klein bool empty() const { return fStages == nullptr; } 144b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 145b24704d35f67f5b460be9c92794892e06adceb46Mike Kleinprivate: 146b24704d35f67f5b460be9c92794892e06adceb46Mike Klein struct StageList { 147b24704d35f67f5b460be9c92794892e06adceb46Mike Klein StageList* prev; 148b24704d35f67f5b460be9c92794892e06adceb46Mike Klein StockStage stage; 149b24704d35f67f5b460be9c92794892e06adceb46Mike Klein void* ctx; 150b24704d35f67f5b460be9c92794892e06adceb46Mike Klein }; 151b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 1523b92b6907a6b9f7020a7589ad07cad2472fe4e86Mike Klein const SkJumper_Engine& build_pipeline(void**) const; 153b24704d35f67f5b460be9c92794892e06adceb46Mike Klein void unchecked_append(StockStage, void*); 1548729e5bbf7c436fd7c7c13182adbbfb419f566b5Mike Klein 155b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkArenaAlloc* fAlloc; 156b24704d35f67f5b460be9c92794892e06adceb46Mike Klein StageList* fStages; 1579fff11133d1890a2733e8a61ba976492fe800c99Mike Klein int fNumStages; 158b24704d35f67f5b460be9c92794892e06adceb46Mike Klein int fSlotsNeeded; 159b24704d35f67f5b460be9c92794892e06adceb46Mike Klein}; 160b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 161b24704d35f67f5b460be9c92794892e06adceb46Mike Kleintemplate <size_t bytes> 162b24704d35f67f5b460be9c92794892e06adceb46Mike Kleinclass SkRasterPipeline_ : public SkRasterPipeline { 163b24704d35f67f5b460be9c92794892e06adceb46Mike Kleinpublic: 164b24704d35f67f5b460be9c92794892e06adceb46Mike Klein SkRasterPipeline_() 16514a6430b7bcf92bcabf4aef18805969d1335aab1Florin Malita : SkRasterPipeline(&fBuiltinAlloc) {} 1661859f69d20e433b86714e5b9002121f2b20a5fc6Mike Klein 167aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868Mike Kleinprivate: 16814a6430b7bcf92bcabf4aef18805969d1335aab1Florin Malita SkSTArenaAlloc<bytes> fBuiltinAlloc; 169281b33fdd909ee3f43192cdf950ce00e3df62407mtklein}; 170281b33fdd909ee3f43192cdf950ce00e3df62407mtklein 171b24704d35f67f5b460be9c92794892e06adceb46Mike Klein 172281b33fdd909ee3f43192cdf950ce00e3df62407mtklein#endif//SkRasterPipeline_DEFINED 173