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 "android/frameworks/sensorservice/1.0/ISensorManager.h"
30 #include "android/frameworks/sensorservice/1.0/types.h"
31 #include "utils/Timers.h"
32 
33 namespace android {
34 
35 using ::android::frameworks::sensorservice::V1_0::IEventQueue;
36 using ::android::frameworks::sensorservice::V1_0::IEventQueueCallback;
37 using ::android::hardware::sensors::V1_0::Event;
38 using ::android::hardware::Return;
39 using ::android::hardware::Void;
40 
41 class EmulatedScene : public RefBase {
42  public:
43   EmulatedScene(int sensor_width_px, int sensor_height_px,
44                 float sensor_sensitivity, int sensor_orientation,
45                 bool is_front_facing);
46   ~EmulatedScene();
47 
48   void InitializeSensorQueue();
49 
50   void Initialize(int sensor_width_px, int sensor_height_px,
51                   float sensor_sensitivity);
52 
53   // Set the filter coefficients for the red, green, and blue filters on the
54   // sensor. Used as an optimization to pre-calculate various illuminance
55   // values. Two different green filters can be provided, to account for
56   // possible cross-talk on a Bayer sensor. Must be called before
57   // calculateScene.
58   void SetColorFilterXYZ(float rX, float rY, float rZ, float grX, float grY,
59                          float grZ, float gbX, float gbY, float gbZ, float bX,
60                          float bY, float bZ);
61 
62   // Set time of day (24-hour clock). This controls the general light levels
63   // in the scene. Must be called before calculateScene.
64   void SetHour(int hour);
65   // Get current hour
66   int GetHour() const;
67 
68   // Set the duration of exposure for determining luminous exposure.
69   // Must be called before calculateScene
70   void SetExposureDuration(float seconds);
71 
72   // Set test pattern mode; this draws a solid-color image set to the color
73   // defined by test pattern data
74   void SetTestPattern(bool enabled);
75   void SetTestPatternData(uint32_t data[4]);
76 
77   // Calculate scene information for current hour and the time offset since
78   // the hour. Resets pixel readout location to 0,0
79   void CalculateScene(nsecs_t time, int32_t handshake_divider);
80 
81   // Set sensor pixel readout location.
82   void SetReadoutPixel(int x, int y);
83 
84   // Get sensor response in physical units (electrons) for light hitting the
85   // current readout pixel, after passing through color filters. The readout
86   // pixel will be auto-incremented horizontally. The returned array can be
87   // indexed with ColorChannels.
88   const uint32_t* GetPixelElectrons();
89 
90   // Get sensor response in physical units (electrons) for light hitting the
91   // current readout pixel, after passing through color filters. The readout
92   // pixel will be auto-incremented vertically. The returned array can be
93   // indexed with ColorChannels.
94   const uint32_t* GetPixelElectronsColumn();
95 
96   enum ColorChannels { R = 0, Gr, Gb, B, Y, Cb, Cr, NUM_CHANNELS };
97 
98   static const int kSceneWidth = 20;
99   static const int kSceneHeight = 20;
100 
101  private:
102   class SensorHandler : public IEventQueueCallback {
103    public:
SensorHandler(wp<EmulatedScene> scene)104     SensorHandler(wp<EmulatedScene> scene) : scene_(scene) {
105     }
106 
107     // IEventQueueCallback interface
108     Return<void> onEvent(const Event& e) override;
109 
110    private:
111     wp<EmulatedScene> scene_;
112   };
113 
114   void InitiliazeSceneRotation(bool clock_wise);
115 
116   int32_t sensor_handle_;
117   sp<IEventQueue> sensor_event_queue_;
118   std::atomic_uint32_t screen_rotation_;
119   uint8_t scene_rot0_[kSceneWidth*kSceneHeight];
120   uint8_t scene_rot90_[kSceneWidth*kSceneHeight];
121   uint8_t scene_rot180_[kSceneWidth*kSceneHeight];
122   uint8_t scene_rot270_[kSceneWidth*kSceneHeight];
123   uint8_t *current_scene_;
124   int32_t sensor_orientation_;
125   bool is_front_facing_;
126 
127   // Sensor color filtering coefficients in XYZ
128   float filter_r_[3];
129   float filter_gr_[3];
130   float filter_gb_[3];
131   float filter_b_[3];
132 
133   int offset_x_, offset_y_;
134   int map_div_;
135 
136   int handshake_x_, handshake_y_;
137 
138   int sensor_width_;
139   int sensor_height_;
140   int current_x_;
141   int current_y_;
142   int sub_x_;
143   int sub_y_;
144   int scene_x_;
145   int scene_y_;
146   int scene_idx_;
147   uint32_t* current_scene_material_;
148 
149   int hour_;
150   float exposure_duration_;
151   float sensor_sensitivity_;  // electrons per lux-second
152 
153   bool test_pattern_mode_;  // SOLID_COLOR only
154   uint32_t test_pattern_data_[4];
155 
156   enum Materials {
157     GRASS = 0,
158     GRASS_SHADOW,
159     HILL,
160     WALL,
161     ROOF,
162     DOOR,
163     CHIMNEY,
164     WINDOW,
165     SUN,
166     SKY,
167     MOON,
168     NUM_MATERIALS
169   };
170 
171   uint32_t current_colors_[NUM_MATERIALS * NUM_CHANNELS];
172 
173   /**
174    * Constants for scene definition. These are various degrees of approximate.
175    */
176 
177   // Fake handshake parameters. Two shake frequencies per axis, plus magnitude
178   // as a fraction of a scene tile, and relative magnitudes for the frequencies
179   static const float kHorizShakeFreq1;
180   static const float kHorizShakeFreq2;
181   static const float kVertShakeFreq1;
182   static const float kVertShakeFreq2;
183   static const float kFreq1Magnitude;
184   static const float kFreq2Magnitude;
185 
186   static const float kShakeFraction;
187 
188   // Aperture of imaging lens
189   static const float kAperture;
190 
191   // Sun, moon illuminance levels in 2-hour increments. These don't match any
192   // real day anywhere.
193   static const uint32_t kTimeStep = 2;
194   static const float kSunlight[];
195   static const float kMoonlight[];
196   static const int kSunOverhead;
197   static const int kMoonOverhead;
198 
199   // Illumination levels for various conditions, in lux
200   static const float kDirectSunIllum;
201   static const float kDaylightShadeIllum;
202   static const float kSunsetIllum;
203   static const float kTwilightIllum;
204   static const float kFullMoonIllum;
205   static const float kClearNightIllum;
206   static const float kStarIllum;
207   static const float kLivingRoomIllum;
208 
209   // Chromaticity of various illumination sources
210   static const float kIncandescentXY[2];
211   static const float kDirectSunlightXY[2];
212   static const float kDaylightXY[2];
213   static const float kNoonSkyXY[2];
214   static const float kMoonlightXY[2];
215   static const float kSunsetXY[2];
216 
217   static const uint8_t kSelfLit;
218   static const uint8_t kShadowed;
219   static const uint8_t kSky;
220 
221   static const float kMaterials_xyY[NUM_MATERIALS][3];
222   static const uint8_t kMaterialsFlags[NUM_MATERIALS];
223 
224   static const uint8_t kScene[];
225 };
226 
227 }  // namespace android
228 
229 #endif  // HW_EMULATOR_CAMERA2_SCENE_H
230