blob: 485c6e0d894c3af6e9f2e16d6448b67890abcb7e [file] [log] [blame]
Mike Kleine1caee12017-02-15 13:31:12 -05001/*
2 * Copyright 2017 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
Mike Kleine1caee12017-02-15 13:31:12 -05008#include "SkJumper.h"
Mike Klein1b9b7d52018-02-27 10:37:40 -05009#include "SkOpts.h"
Mike Kleine1caee12017-02-15 13:31:12 -050010#include "SkRasterPipeline.h"
11#include "SkTemplates.h"
Mike Klein91ad0742017-02-22 14:04:38 -050012
Mike Klein1b9b7d52018-02-27 10:37:40 -050013SkRasterPipeline::StartPipelineFn SkRasterPipeline::build_pipeline(void** ip) const {
Mike Klein5cc94cc2018-03-07 17:04:18 +000014#ifndef SK_JUMPER_DISABLE_8BIT
Mike Klein1b9b7d52018-02-27 10:37:40 -050015 // We'll try to build a lowp pipeline, but if that fails fallback to a highp float pipeline.
Mike Klein5cc94cc2018-03-07 17:04:18 +000016 void** reset_point = ip;
Mike Klein1b9b7d52018-02-27 10:37:40 -050017
18 // Stages are stored backwards in fStages, so we reverse here, back to front.
19 *--ip = (void*)SkOpts::just_return_lowp;
Mike Klein8c3d5152017-06-19 14:37:10 -070020 for (const StageList* st = fStages; st; st = st->prev) {
Ethan Nicholas26a9aad2018-03-27 14:10:52 -040021 SkOpts::StageFn fn;
22 if (!st->rawFunction && (fn = SkOpts::stages_lowp[st->stage])) {
Mike Kleinbba02c22017-06-02 10:03:30 -040023 if (st->ctx) {
24 *--ip = st->ctx;
25 }
26 *--ip = (void*)fn;
Mike Klein8c3d5152017-06-19 14:37:10 -070027 } else {
Mike Klein8c3d5152017-06-19 14:37:10 -070028 ip = reset_point;
29 break;
Mike Kleinbba02c22017-06-02 10:03:30 -040030 }
31 }
Mike Klein8c3d5152017-06-19 14:37:10 -070032 if (ip != reset_point) {
Mike Klein1b9b7d52018-02-27 10:37:40 -050033 return SkOpts::start_pipeline_lowp;
Mike Klein8c3d5152017-06-19 14:37:10 -070034 }
Mike Kleinbba02c22017-06-02 10:03:30 -040035#endif
Mike Kleinbba02c22017-06-02 10:03:30 -040036
Mike Klein1b9b7d52018-02-27 10:37:40 -050037 *--ip = (void*)SkOpts::just_return_highp;
Mike Kleinbba02c22017-06-02 10:03:30 -040038 for (const StageList* st = fStages; st; st = st->prev) {
Mike Kleinb24704d2017-05-24 07:53:00 -040039 if (st->ctx) {
40 *--ip = st->ctx;
Mike Klein0a76b412017-05-22 12:01:59 -040041 }
Ethan Nicholas26a9aad2018-03-27 14:10:52 -040042 if (st->rawFunction) {
43 *--ip = (void*)st->stage;
44 } else {
45 *--ip = (void*)SkOpts::stages_highp[st->stage];
46 }
Mike Klein0a76b412017-05-22 12:01:59 -040047 }
Mike Klein1b9b7d52018-02-27 10:37:40 -050048 return SkOpts::start_pipeline_highp;
Mike Klein0a76b412017-05-22 12:01:59 -040049}
50
Mike Klein45c16fa2017-07-18 18:15:13 -040051void SkRasterPipeline::run(size_t x, size_t y, size_t w, size_t h) const {
Mike Kleinb24704d2017-05-24 07:53:00 -040052 if (this->empty()) {
Brian Osmanbcd86372017-05-22 19:45:09 +000053 return;
54 }
Mike Klein9f52e982017-05-20 10:10:38 -040055
Mike Kleinb24704d2017-05-24 07:53:00 -040056 // Best to not use fAlloc here... we can't bound how often run() will be called.
57 SkAutoSTMalloc<64, void*> program(fSlotsNeeded);
Mike Kleine1caee12017-02-15 13:31:12 -050058
Mike Klein1b9b7d52018-02-27 10:37:40 -050059 auto start_pipeline = this->build_pipeline(program.get() + fSlotsNeeded);
60 start_pipeline(x,y,x+w,y+h, program.get());
Mike Klein0a76b412017-05-22 12:01:59 -040061}
Mike Kleine1caee12017-02-15 13:31:12 -050062
Mike Klein45c16fa2017-07-18 18:15:13 -040063std::function<void(size_t, size_t, size_t, size_t)> SkRasterPipeline::compile() const {
Mike Kleinb24704d2017-05-24 07:53:00 -040064 if (this->empty()) {
Mike Klein45c16fa2017-07-18 18:15:13 -040065 return [](size_t, size_t, size_t, size_t) {};
Brian Osmanbcd86372017-05-22 19:45:09 +000066 }
Mike Klein0a76b412017-05-22 12:01:59 -040067
Mike Kleinb5e48422017-05-30 18:09:29 -040068 void** program = fAlloc->makeArray<void*>(fSlotsNeeded);
Mike Klein0a76b412017-05-22 12:01:59 -040069
Mike Klein1b9b7d52018-02-27 10:37:40 -050070 auto start_pipeline = this->build_pipeline(program + fSlotsNeeded);
Mike Klein45c16fa2017-07-18 18:15:13 -040071 return [=](size_t x, size_t y, size_t w, size_t h) {
Mike Klein856b3c32017-08-29 13:38:09 -040072 start_pipeline(x,y,x+w,y+h, program);
Mike Kleind1fe9522017-02-17 09:41:09 -050073 };
Mike Kleine1caee12017-02-15 13:31:12 -050074}