1 /*
2  * Copyright (C) 2012 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 /**
18  * The Scene class implements a simple physical simulation of a scene, using the
19  * CIE 1931 colorspace to represent light in physical units (lux).
20  *
21  * It's fairly approximate, but does provide a scene with realistic widely
22  * variable illumination levels and colors over time.
23  *
24  */
25 
26 #ifndef HW_EMULATOR_CAMERA2_SCENE_H
27 #define HW_EMULATOR_CAMERA2_SCENE_H
28 
29 #include "utils/Timers.h"
30 
31 namespace android {
32 
33 class Scene {
34   public:
35     Scene(int sensorWidthPx,
36             int sensorHeightPx,
37             float sensorSensitivity);
38     ~Scene();
39 
40     // Set the filter coefficients for the red, green, and blue filters on the
41     // sensor. Used as an optimization to pre-calculate various illuminance
42     // values. Two different green filters can be provided, to account for
43     // possible cross-talk on a Bayer sensor. Must be called before
44     // calculateScene.
45     void setColorFilterXYZ(
46         float rX, float rY, float rZ,
47         float grX, float grY, float grZ,
48         float gbX, float gbY, float gbZ,
49         float bX, float bY, float bZ);
50 
51     // Set time of day (24-hour clock). This controls the general light levels
52     // in the scene. Must be called before calculateScene
53     void setHour(int hour);
54     // Get current hour
55     int getHour();
56 
57     // Set the duration of exposure for determining luminous exposure.
58     // Must be called before calculateScene
59     void setExposureDuration(float seconds);
60 
61     // Calculate scene information for current hour and the time offset since
62     // the hour. Must be called at least once before calling getLuminousExposure.
63     // Resets pixel readout location to 0,0
64     void calculateScene(nsecs_t time);
65 
66     // Set sensor pixel readout location.
setReadoutPixel(int x,int y)67     inline void setReadoutPixel(int x, int y) {
68         mCurrentX = x;
69         mCurrentY = y;
70         mSubX = (x + mOffsetX + mHandshakeX) % mMapDiv;
71         mSubY = (y + mOffsetY + mHandshakeY) % mMapDiv;
72         mSceneX = (x + mOffsetX + mHandshakeX) / mMapDiv;
73         mSceneY = (y + mOffsetY + mHandshakeY) / mMapDiv;
74         mSceneIdx = mSceneY * kSceneWidth + mSceneX;
75         mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
76     }
77 
78     // Get sensor response in physical units (electrons) for light hitting the
79     // current readout pixel, after passing through color filters. The readout
80     // pixel will be auto-incremented. The returned array can be indexed with
81     // ColorChannels.
getPixelElectrons()82     inline const uint32_t* getPixelElectrons() {
83         const uint32_t *pixel = mCurrentSceneMaterial;
84         mCurrentX++;
85         mSubX++;
86         if (mCurrentX >= mSensorWidth) {
87             mCurrentX = 0;
88             mCurrentY++;
89             if (mCurrentY >= mSensorHeight) mCurrentY = 0;
90             setReadoutPixel(mCurrentX, mCurrentY);
91         } else if (mSubX > mMapDiv) {
92             mSceneIdx++;
93             mSceneX++;
94             mCurrentSceneMaterial = &(mCurrentColors[kScene[mSceneIdx]]);
95             mSubX = 0;
96         }
97         return pixel;
98     }
99 
100     enum ColorChannels {
101         R = 0,
102         Gr,
103         Gb,
104         B,
105         Y,
106         Cb,
107         Cr,
108         NUM_CHANNELS
109     };
110 
111     // Max scene width and height. Calculation for larger scene consumes much
112     // CPU resource. So we put a limit here.
113     static const int kMaxWidth;
114     static const int kMaxHeight;
115 
116   private:
117     // Sensor color filtering coefficients in XYZ
118     float mFilterR[3];
119     float mFilterGr[3];
120     float mFilterGb[3];
121     float mFilterB[3];
122 
123     int mOffsetX, mOffsetY;
124     int mMapDiv;
125 
126     int mHandshakeX, mHandshakeY;
127 
128     int mSensorWidth;
129     int mSensorHeight;
130     int mCurrentX;
131     int mCurrentY;
132     int mSubX;
133     int mSubY;
134     int mSceneX;
135     int mSceneY;
136     int mSceneIdx;
137     uint32_t *mCurrentSceneMaterial;
138 
139     int mHour;
140     float mExposureDuration;
141     //float mSensorSensitivity;
142 
143     enum Materials {
144         GRASS = 0,
145         GRASS_SHADOW,
146         HILL,
147         WALL,
148         ROOF,
149         DOOR,
150         CHIMNEY,
151         WINDOW,
152         SUN,
153         SKY,
154         MOON,
155         NUM_MATERIALS
156     };
157 
158     uint32_t mCurrentColors[NUM_MATERIALS*NUM_CHANNELS];
159 
160     /**
161      * Constants for scene definition. These are various degrees of approximate.
162      */
163 
164     // Fake handshake parameters. Two shake frequencies per axis, plus magnitude
165     // as a fraction of a scene tile, and relative magnitudes for the frequencies
166     static const float kHorizShakeFreq1;
167     static const float kHorizShakeFreq2;
168     static const float kVertShakeFreq1;
169     static const float kVertShakeFreq2;
170     static const float kFreq1Magnitude;
171     static const float kFreq2Magnitude;
172 
173     static const float kShakeFraction;
174 
175     // RGB->YUV conversion
176     static const float kRgb2Yuv[12];
177 
178     // Aperture of imaging lens
179     static const float kAperture;
180 
181     // Sun, moon illuminance levels in 2-hour increments. These don't match any
182     // real day anywhere.
183     static const uint32_t kTimeStep = 2;
184     static const float kSunlight[];
185     static const float kMoonlight[];
186     static const int kSunOverhead;
187     static const int kMoonOverhead;
188 
189     // Illumination levels for various conditions, in lux
190     static const float kDirectSunIllum;
191     static const float kDaylightShadeIllum;
192     static const float kSunsetIllum;
193     static const float kTwilightIllum;
194     static const float kFullMoonIllum;
195     static const float kClearNightIllum;
196     static const float kStarIllum;
197     static const float kLivingRoomIllum;
198 
199     // Chromaticity of various illumination sources
200     static const float kIncandescentXY[2];
201     static const float kDirectSunlightXY[2];
202     static const float kDaylightXY[2];
203     static const float kNoonSkyXY[2];
204     static const float kMoonlightXY[2];
205     static const float kSunsetXY[2];
206 
207     static const uint8_t kSelfLit;
208     static const uint8_t kShadowed;
209     static const uint8_t kSky;
210 
211     static const float kMaterials_xyY[NUM_MATERIALS][3];
212     static const uint8_t kMaterialsFlags[NUM_MATERIALS];
213 
214     static const int kSceneWidth;
215     static const int kSceneHeight;
216     static const uint8_t kScene[];
217 };
218 
219 }
220 
221 #endif // HW_EMULATOR_CAMERA2_SCENE_H
222