1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "rsContext.h"
18 #include "rsSampler.h"
19 #include "rs.h"
20 
21 using namespace android;
22 using namespace android::renderscript;
23 
24 
Sampler(Context * rsc)25 Sampler::Sampler(Context *rsc) : ObjectBase(rsc) {
26     // Should not get called.
27     rsAssert(0);
28 }
29 
Sampler(Context * rsc,RsSamplerValue magFilter,RsSamplerValue minFilter,RsSamplerValue wrapS,RsSamplerValue wrapT,RsSamplerValue wrapR,float aniso)30 Sampler::Sampler(Context *rsc,
31                  RsSamplerValue magFilter,
32                  RsSamplerValue minFilter,
33                  RsSamplerValue wrapS,
34                  RsSamplerValue wrapT,
35                  RsSamplerValue wrapR,
36                  float aniso) : ObjectBase(rsc) {
37     mHal.state.magFilter = magFilter;
38     mHal.state.minFilter = minFilter;
39     mHal.state.wrapS = wrapS;
40     mHal.state.wrapT = wrapT;
41     mHal.state.wrapR = wrapR;
42     mHal.state.aniso = aniso;
43 
44     mRSC->mHal.funcs.sampler.init(mRSC, this);
45 }
46 
~Sampler()47 Sampler::~Sampler() {
48     mRSC->mHal.funcs.sampler.destroy(mRSC, this);
49 }
50 
preDestroy() const51 void Sampler::preDestroy() const {
52     for (uint32_t ct = 0; ct < mRSC->mStateSampler.mAllSamplers.size(); ct++) {
53         if (mRSC->mStateSampler.mAllSamplers[ct] == this) {
54             mRSC->mStateSampler.mAllSamplers.removeAt(ct);
55             break;
56         }
57     }
58 }
59 
bindToContext(SamplerState * ss,uint32_t slot)60 void Sampler::bindToContext(SamplerState *ss, uint32_t slot) {
61     ss->mSamplers[slot].set(this);
62     mBoundSlot = slot;
63 }
64 
unbindFromContext(SamplerState * ss)65 void Sampler::unbindFromContext(SamplerState *ss) {
66     int32_t slot = mBoundSlot;
67     mBoundSlot = -1;
68     ss->mSamplers[slot].clear();
69 }
70 
serialize(Context * rsc,OStream * stream) const71 void Sampler::serialize(Context *rsc, OStream *stream) const {
72 }
73 
createFromStream(Context * rsc,IStream * stream)74 Sampler *Sampler::createFromStream(Context *rsc, IStream *stream) {
75     return nullptr;
76 }
77 
getSampler(Context * rsc,RsSamplerValue magFilter,RsSamplerValue minFilter,RsSamplerValue wrapS,RsSamplerValue wrapT,RsSamplerValue wrapR,float aniso)78 ObjectBaseRef<Sampler> Sampler::getSampler(Context *rsc,
79                                            RsSamplerValue magFilter,
80                                            RsSamplerValue minFilter,
81                                            RsSamplerValue wrapS,
82                                            RsSamplerValue wrapT,
83                                            RsSamplerValue wrapR,
84                                            float aniso) {
85     ObjectBaseRef<Sampler> returnRef;
86     ObjectBase::asyncLock();
87     for (uint32_t ct = 0; ct < rsc->mStateSampler.mAllSamplers.size(); ct++) {
88         Sampler *existing = rsc->mStateSampler.mAllSamplers[ct];
89         if (existing->mHal.state.magFilter != magFilter) continue;
90         if (existing->mHal.state.minFilter != minFilter ) continue;
91         if (existing->mHal.state.wrapS != wrapS) continue;
92         if (existing->mHal.state.wrapT != wrapT) continue;
93         if (existing->mHal.state.wrapR != wrapR) continue;
94         if (existing->mHal.state.aniso != aniso) continue;
95         returnRef.set(existing);
96         ObjectBase::asyncUnlock();
97         return returnRef;
98     }
99     ObjectBase::asyncUnlock();
100 
101     void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Sampler), 0);
102     if (!allocMem) {
103         rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
104         return nullptr;
105     }
106 
107     Sampler *s = new (allocMem) Sampler(rsc, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
108     returnRef.set(s);
109 
110 #ifdef RS_FIND_OFFSETS
111     ALOGE("pointer for sampler: %p", s);
112     ALOGE("pointer for sampler.drv: %p", &s->mHal.drv);
113 #endif
114 
115     ObjectBase::asyncLock();
116     rsc->mStateSampler.mAllSamplers.push(s);
117     ObjectBase::asyncUnlock();
118 
119     return returnRef;
120 }
121 
operator delete(void * ptr)122 void Sampler::operator delete(void* ptr) {
123     if (ptr) {
124         Sampler *s = (Sampler*) ptr;
125         s->getContext()->mHal.funcs.freeRuntimeMem(ptr);
126     }
127 }
128 
129 
130 ////////////////////////////////
131 
132 namespace android {
133 namespace renderscript {
134 
rsi_SamplerCreate(Context * rsc,RsSamplerValue magFilter,RsSamplerValue minFilter,RsSamplerValue wrapS,RsSamplerValue wrapT,RsSamplerValue wrapR,float aniso)135 RsSampler rsi_SamplerCreate(Context * rsc,
136                             RsSamplerValue magFilter,
137                             RsSamplerValue minFilter,
138                             RsSamplerValue wrapS,
139                             RsSamplerValue wrapT,
140                             RsSamplerValue wrapR,
141                             float aniso) {
142     ObjectBaseRef<Sampler> s = Sampler::getSampler(rsc, magFilter, minFilter,
143                                                    wrapS, wrapT, wrapR, aniso);
144     s->incUserRef();
145     return s.get();
146 }
147 
148 }}
149