SkRasterPipeline.cpp revision 04adfda9c74481d0b640c0ce18864588babfcdf6
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 "SkOpts.h"
9#include "SkRasterPipeline.h"
10
11SkRasterPipeline::SkRasterPipeline() {
12    fBodyStart = SkOpts::body[just_return];
13    fTailStart = SkOpts::tail[just_return];
14}
15
16void SkRasterPipeline::append(void (*body)(), void (*tail)(), void* ctx) {
17    // Each stage holds its own context and the next function to call.
18    // So the pipeline itself has to hold onto the first function that starts the pipeline.
19    (fBody.empty() ? fBodyStart : fBody.back().fNext) = body;
20    (fTail.empty() ? fTailStart : fTail.back().fNext) = tail;
21
22    // Each last stage starts with its next function set to JustReturn as a safety net.
23    // It'll be overwritten by the next call to append().
24    fBody.push_back({ SkOpts::body[just_return], ctx });
25    fTail.push_back({ SkOpts::tail[just_return], ctx });
26}
27
28void SkRasterPipeline::append(StockStage stage, void* ctx) {
29    this->append(SkOpts::body[stage], SkOpts::tail[stage], ctx);
30}
31
32void SkRasterPipeline::extend(const SkRasterPipeline& src) {
33    SkASSERT(src.fBody.count() == src.fTail.count());
34
35    auto body = src.fBodyStart,
36         tail = src.fTailStart;
37    for (int i = 0; i < src.fBody.count(); i++) {
38        SkASSERT(src.fBody[i].fCtx == src.fTail[i].fCtx);
39        this->append(body, tail, src.fBody[i].fCtx);
40        body = src.fBody[i].fNext;
41        tail = src.fTail[i].fNext;
42    }
43}
44
45void SkRasterPipeline::run(size_t x, size_t n) {
46    SkOpts::run_pipeline(x,n, fBodyStart,fBody.begin(), fTailStart,fTail.begin());
47}
48