1326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams/*
2326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Copyright (C) 2009 The Android Open Source Project
3326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
4326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * you may not use this file except in compliance with the License.
6326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * You may obtain a copy of the License at
7326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
8326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams *
10326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * Unless required by applicable law or agreed to in writing, software
11326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * See the License for the specific language governing permissions and
14326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams * limitations under the License.
15326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams */
16326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
17326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams#include "rsContext.h"
18fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk#include "rsProgramFragment.h"
191aa5a4eb81b8b88aeb5d2b6f4c47356fd0a62923Jason Sams
20f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers#include <inttypes.h>
21f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
23326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
24326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
25748eb07e805b93c2bf79340d4937963ab739d17cAlex SakhartchoukProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength,
26748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                 const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
27f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers                                 const uintptr_t * params, size_t paramLength)
28afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    : Program(rsc, shaderText, shaderLength, params, paramLength) {
296445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[0] = 1.f;
306445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[1] = 1.f;
316445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[2] = 1.f;
326445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[3] = 1.f;
336445e5210c6d7f8689e94be9026153d017c9545bJason Sams
34f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader, mUserShaderLen,
35748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                   textureNames, textureNamesCount, textureNamesLength);
36f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams}
37f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams
38afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragment::~ProgramFragment() {
39a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.fragment.destroy(mRSC, this);
40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
41326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
42afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) {
43afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (isUserProgram()) {
44af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Attempting to set fixed function emulation color on user program");
45383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot  set fixed function emulation color on user program");
46383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        return;
47383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
48064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    if (mHal.state.constants[0] == NULL) {
49af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Unable to set fixed function emulation color because allocation is missing");
50383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
51e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        return;
52e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    }
536445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[0] = r;
546445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[1] = g;
556445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[2] = b;
566445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[3] = a;
57807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    void *p = rsc->mHal.funcs.allocation.lock1D(rsc, mHal.state.constants[0]);
58807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    memcpy(p, mConstantColor, 4*sizeof(float));
596445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mDirty = true;
60807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
616445e5210c6d7f8689e94be9026153d017c9545bJason Sams}
62334fd9aeacd4221fc8cd1333b2a34fb3b26b3a0dJason Sams
63c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchoukvoid ProgramFragment::setup(Context *rsc, ProgramFragmentState *state) {
64c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    if ((state->mLast.get() == this) && !mDirty) {
65e64c2f172516972abe581ca1b762302dd2ba1199Jason Sams        return;
66c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    }
67c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    state->mLast.set(this);
68c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
69a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
70064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        if (!mHal.state.textures[ct]) {
71f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers            ALOGE("No texture bound for shader id %" PRIuPTR ", texture unit %u", (uintptr_t)this, ct);
72383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
73c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            continue;
74c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        }
75383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
766e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
77a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsc->mHal.funcs.fragment.setActive(rsc, this);
78c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
79326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
80e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid ProgramFragment::serialize(Context *rsc, OStream *stream) const {
81fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
82fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
83afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) {
84fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return NULL;
85fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
86fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
87afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragmentState::ProgramFragmentState() {
88326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mPF = NULL;
89326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
90326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
91afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragmentState::~ProgramFragmentState() {
92225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ObjectBase::checkDelete(mPF);
93225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    mPF = NULL;
94326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
95326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
96afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragmentState::init(Context *rsc) {
97a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams    const char *shaderString =
98a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            RS_SHADER_INTERNAL
99a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "varying lowp vec4 varColor;\n"
100a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "varying vec2 varTex0;\n"
101a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "void main() {\n"
102a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "  lowp vec4 col = UNI_Color;\n"
103a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "  gl_FragColor = col;\n"
104a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams            "}\n";
105e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
106c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<const Element> colorElem = Element::createRef(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
107f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams
108f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    const char *enames[] = { "Color" };
109f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    const Element *eins[] = {colorElem.get()};
110f313dc32d5ea68a7c48fb4ec6e131ec2fb97ce2dJason Sams    ObjectBaseRef<const Element> constInput = Element::create(rsc, 1, eins, enames);
111e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
112a572aca4eb4ddb32c10baa1f529431cfefd756b8Jason Sams    ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false, 0);
113e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
114f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers    uintptr_t tmp[2];
115e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
116f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers    tmp[1] = (uintptr_t)inputType.get();
117e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
118c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
119eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
120a7f5e0406825151660c1c2e75c287e2fc8368023Jason Sams    ProgramFragment *pf = new ProgramFragment(rsc, shaderString, strlen(shaderString),
121748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              NULL, 0, NULL, tmp, 2);
122383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    pf->bindAllocation(rsc, constAlloc, 0);
123383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
124e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
1258ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams    mDefault.set(pf);
1268ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams}
127326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
128afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragmentState::deinit(Context *rsc) {
129f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mDefault.clear();
130f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mLast.clear();
131f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams}
132f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
133326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
134326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
135326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
136383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex SakhartchoukRsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText,
137748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            size_t shaderLength,
138748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            const char** textureNames,
139748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            size_t textureNamesCount,
140748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            const size_t *textureNamesLength,
141f8852d0494a260c583795a96a2a06c49b86a9b10Ian Rogers                                            const uintptr_t * params, size_t paramLength) {
142748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength,
143748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              textureNames, textureNamesCount, textureNamesLength,
144748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              params, paramLength);
145f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams    pf->incUserRef();
146af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("rsi_ProgramFragmentCreate %p", pf);
147f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams    return pf;
148f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams}
149326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
150326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
151326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
152326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
153