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
20326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android;
21326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsusing namespace android::renderscript;
22326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
23748eb07e805b93c2bf79340d4937963ab739d17cAlex SakhartchoukProgramFragment::ProgramFragment(Context *rsc, const char * shaderText, size_t shaderLength,
24748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                 const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
25748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk
26748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                 const uint32_t * params, size_t paramLength)
27afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    : Program(rsc, shaderText, shaderLength, params, paramLength) {
286445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[0] = 1.f;
296445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[1] = 1.f;
306445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[2] = 1.f;
316445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[3] = 1.f;
326445e5210c6d7f8689e94be9026153d017c9545bJason Sams
33748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk    mRSC->mHal.funcs.fragment.init(mRSC, this, mUserShader.string(), mUserShader.length(),
34748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                   textureNames, textureNamesCount, textureNamesLength);
35f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams}
36f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams
37afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragment::~ProgramFragment() {
38a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    mRSC->mHal.funcs.fragment.destroy(mRSC, this);
39326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
40326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
41afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) {
42afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchouk    if (isUserProgram()) {
43af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Attempting to set fixed function emulation color on user program");
44383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Cannot  set fixed function emulation color on user program");
45383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        return;
46383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
47064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk    if (mHal.state.constants[0] == NULL) {
48af12ac6a08651464f8d823add667c706f993b587Steve Block        ALOGE("Unable to set fixed function emulation color because allocation is missing");
49383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk        rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
50e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk        return;
51e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    }
526445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[0] = r;
536445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[1] = g;
546445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[2] = b;
556445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mConstantColor[3] = a;
56807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    void *p = rsc->mHal.funcs.allocation.lock1D(rsc, mHal.state.constants[0]);
57807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    memcpy(p, mConstantColor, 4*sizeof(float));
586445e5210c6d7f8689e94be9026153d017c9545bJason Sams    mDirty = true;
59807fdc4b6f3fb893015ee136565d6151bb2332d3Jason Sams    rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
606445e5210c6d7f8689e94be9026153d017c9545bJason Sams}
61334fd9aeacd4221fc8cd1333b2a34fb3b26b3a0dJason Sams
62c19ff0177a7a0dadfc01b1990f822354fdc95991Alex Sakhartchoukvoid ProgramFragment::setup(Context *rsc, ProgramFragmentState *state) {
63c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    if ((state->mLast.get() == this) && !mDirty) {
64e64c2f172516972abe581ca1b762302dd2ba1199Jason Sams        return;
65c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    }
66c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams    state->mLast.set(this);
67c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams
68a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
69064aa7ed76db9564b041afcd4b75da5b3d12fabaAlex Sakhartchouk        if (!mHal.state.textures[ct]) {
70af12ac6a08651464f8d823add667c706f993b587Steve Block            ALOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
71383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk            rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
72c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams            continue;
73c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams        }
74383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    }
756e9342199959dc9beb5299fefc9775fe8c32620eAlex Sakhartchouk
76a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    rsc->mHal.funcs.fragment.setActive(rsc, this);
77c460e55d78cbe8bee95c5c947dfe541218142a5bJason Sams}
78326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
79e3150cfb3edb028407669e4a65e087eae77e718cJason Samsvoid ProgramFragment::serialize(Context *rsc, OStream *stream) const {
80fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
81fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
82afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) {
83fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk    return NULL;
84fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk}
85fb6b614bcea88a587a7ea4530be45ff0ffa0210eAlex Sakhartchouk
86afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragmentState::ProgramFragmentState() {
87326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams    mPF = NULL;
88326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
89326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
90afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex SakhartchoukProgramFragmentState::~ProgramFragmentState() {
91225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    ObjectBase::checkDelete(mPF);
92225afd317e101a7be5fe02c0a86361146ea89f05Jason Sams    mPF = NULL;
93326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
94326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
95afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragmentState::init(Context *rsc) {
96e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    String8 shaderString(RS_SHADER_INTERNAL);
97e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    shaderString.append("varying lowp vec4 varColor;\n");
987ffcaf20cbb115326f3d72a983835d6c314a4cefAlex Sakhartchouk    shaderString.append("varying vec2 varTex0;\n");
99e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    shaderString.append("void main() {\n");
100e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    shaderString.append("  lowp vec4 col = UNI_Color;\n");
101e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    shaderString.append("  gl_FragColor = col;\n");
102e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    shaderString.append("}\n");
103e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
104c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<const Element> colorElem = Element::createRef(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
105c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    Element::Builder builder;
106c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    builder.add(colorElem.get(), "Color", 1);
107c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<const Element> constInput = builder.create(rsc);
108e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
109c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1, 0, 0, false, false);
110e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
11184e4027f83b20af59f5b1fc52be6e45f159d3970Alex Sakhartchouk    uint32_t tmp[2];
112e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk    tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
113c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    tmp[1] = (uint32_t)inputType.get();
114e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
115c700e649ca44d0dcff8b271e42d949ea72fe3c63Alex Sakhartchouk    Allocation *constAlloc = Allocation::createAllocation(rsc, inputType.get(),
116eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams                              RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
117748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk    ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), shaderString.length(),
118748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              NULL, 0, NULL, tmp, 2);
119383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    pf->bindAllocation(rsc, constAlloc, 0);
120383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex Sakhartchouk    pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
121e7ae69f4a70f1813cf8086ebd9714192c635300aAlex Sakhartchouk
1228ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams    mDefault.set(pf);
1238ce125be69531dbf3a7e856d5e59d1b8e2789db0Jason Sams}
124326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
125afb743aca56c18beb7ab924e75cb6e070ef3e55aAlex Sakhartchoukvoid ProgramFragmentState::deinit(Context *rsc) {
126f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mDefault.clear();
127f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams    mLast.clear();
128f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams}
129f2649a961db2995e9e24a6c98f8a419f1496c1b7Jason Sams
130326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace android {
131326e0ddf89e8df2837752fbfd7a014814b32082cJason Samsnamespace renderscript {
132326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
133383e5b1f68c321a77bfd7466fa1171a9bfab4a6fAlex SakhartchoukRsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText,
134748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            size_t shaderLength,
135748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            const char** textureNames,
136748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            size_t textureNamesCount,
137748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            const size_t *textureNamesLength,
138748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                            const uint32_t * params, size_t paramLength) {
139748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength,
140748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              textureNames, textureNamesCount, textureNamesLength,
141748eb07e805b93c2bf79340d4937963ab739d17cAlex Sakhartchouk                                              params, paramLength);
142f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams    pf->incUserRef();
143af12ac6a08651464f8d823add667c706f993b587Steve Block    //ALOGE("rsi_ProgramFragmentCreate %p", pf);
144f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams    return pf;
145f2e4fa215c420cf0f8d226e9a59acb1f312e5e40Jason Sams}
146326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
147326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
148326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams}
149326e0ddf89e8df2837752fbfd7a014814b32082cJason Sams
150