blob: 0679621db3ead771b1b9b4d29cee38051741ecad [file] [log] [blame]
Iliyan Malchev202a77d2012-06-11 14:41:12 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef GRALLOC_PRIV_H_
19#define GRALLOC_PRIV_H_
20
21#include <stdint.h>
22#include <limits.h>
23#include <sys/cdefs.h>
24#include <hardware/gralloc.h>
25#include <pthread.h>
26#include <errno.h>
27#include <unistd.h>
28
29#include <cutils/native_handle.h>
30
31#include <linux/fb.h>
32
33#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
34#include "overlayLib.h"
35using namespace overlay;
36#endif
37
38#include <cutils/log.h>
39
40enum {
41 /* gralloc usage bits indicating the type
42 * of allocation that should be used */
43
44 /* ADSP heap is deprecated, use only if using pmem */
45 GRALLOC_USAGE_PRIVATE_ADSP_HEAP = GRALLOC_USAGE_PRIVATE_0,
46 /* SF heap is used for application buffers, is not secured */
47 GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP = GRALLOC_USAGE_PRIVATE_1,
48 /* SMI heap is deprecated, use only if using pmem */
49 GRALLOC_USAGE_PRIVATE_SMI_HEAP = GRALLOC_USAGE_PRIVATE_2,
50 /* SYSTEM heap comes from kernel vmalloc,
51 * can never be uncached, is not secured*/
52 GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_3,
53 /* IOMMU heap comes from manually allocated pages,
54 * can be cached/uncached, is not secured */
55 GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = 0x01000000,
56 /* MM heap is a carveout heap for video, can be secured*/
57 GRALLOC_USAGE_PRIVATE_MM_HEAP = 0x02000000,
58 /* WRITEBACK heap is a carveout heap for writeback, can be secured*/
59 GRALLOC_USAGE_PRIVATE_WRITEBACK_HEAP = 0x04000000,
60 /* CAMERA heap is a carveout heap for camera, is not secured*/
61 GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x08000000,
62
63 /* Set this for allocating uncached memory (using O_DSYNC)
64 * cannot be used with noncontiguous heaps */
65 GRALLOC_USAGE_PRIVATE_UNCACHED = 0x00100000,
66
67 /* This flag needs to be set when using a non-contiguous heap from ION.
68 * If not set, the system heap is assumed to be coming from ashmem
69 */
70 GRALLOC_USAGE_PRIVATE_ION = 0x00200000,
71
72 /* This flag can be set to disable genlock synchronization
73 * for the gralloc buffer. If this flag is set the caller
74 * is required to perform explicit synchronization.
75 * WARNING - flag is outside the standard PRIVATE region
76 * and may need to be moved if the gralloc API changes
77 */
78 GRALLOC_USAGE_PRIVATE_UNSYNCHRONIZED = 0X00400000,
79
80 /* Set this flag when you need to avoid mapping the memory in userspace */
81 GRALLOC_USAGE_PRIVATE_DO_NOT_MAP = 0X00800000,
82
83 /* Buffer content should be displayed on an external display only */
84 GRALLOC_USAGE_EXTERNAL_ONLY = 0x00010000,
85
86 /* Only this buffer content should be displayed on external, even if
87 * other EXTERNAL_ONLY buffers are available. Used during suspend.
88 */
89 GRALLOC_USAGE_EXTERNAL_BLOCK = 0x00020000,
90};
91
92enum {
93 /* Gralloc perform enums
94 */
95 GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 0x080000001,
96};
97
98
99enum {
100 GPU_COMPOSITION,
101 C2D_COMPOSITION,
102 MDP_COMPOSITION,
103 CPU_COMPOSITION,
104};
105
106/* numbers of max buffers for page flipping */
107#define NUM_FRAMEBUFFERS_MIN 2
108#define NUM_FRAMEBUFFERS_MAX 3
109
110/* number of default bufers for page flipping */
111#define NUM_DEF_FRAME_BUFFERS 2
112#define NO_SURFACEFLINGER_SWAPINTERVAL
113#define INTERLACE_MASK 0x80
114#define S3D_FORMAT_MASK 0xFF000
115#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
116#define DEVICE_PMEM "/dev/pmem"
117#define DEVICE_PMEM_ADSP "/dev/pmem_adsp"
118#define DEVICE_PMEM_SMIPOOL "/dev/pmem_smipool"
119/*****************************************************************************/
120#ifdef __cplusplus
121
122//XXX: Remove framebuffer specific classes and defines to a different header
123template <class T>
124struct Node
125{
126 T data;
127 Node<T> *next;
128};
129
130template <class T>
131class Queue
132{
133public:
134 Queue(): front(NULL), back(NULL), len(0) {dummy = new T;}
135 ~Queue()
136 {
137 clear();
138 delete dummy;
139 }
140 void push(const T& item) //add an item to the back of the queue
141 {
142 if(len != 0) { //if the queue is not empty
143 back->next = new Node<T>; //create a new node
144 back = back->next; //set the new node as the back node
145 back->data = item;
146 back->next = NULL;
147 } else {
148 back = new Node<T>;
149 back->data = item;
150 back->next = NULL;
151 front = back;
152 }
153 len++;
154 }
155 void pop() //remove the first item from the queue
156 {
157 if (isEmpty())
158 return; //if the queue is empty, no node to dequeue
159 T item = front->data;
160 Node<T> *tmp = front;
161 front = front->next;
162 delete tmp;
163 if(front == NULL) //if the queue is empty, update the back pointer
164 back = NULL;
165 len--;
166 return;
167 }
168 T& getHeadValue() const //return the value of the first item in the queue
169 { //without modification to the structure
170 if (isEmpty()) {
171 ALOGE("Error can't get head of empty queue");
172 return *dummy;
173 }
174 return front->data;
175 }
176
177 bool isEmpty() const //returns true if no elements are in the queue
178 {
179 return (front == NULL);
180 }
181
182 size_t size() const //returns the amount of elements in the queue
183 {
184 return len;
185 }
186
187private:
188 Node<T> *front;
189 Node<T> *back;
190 size_t len;
191 void clear()
192 {
193 while (!isEmpty())
194 pop();
195 }
196 T *dummy;
197};
198#endif
199
200enum {
201 /* OEM specific HAL formats */
202 HAL_PIXEL_FORMAT_NV12_ENCODEABLE = 0x102,
203 HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x108,
204 HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
205 HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x10A,
206 HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x10B,
207 HAL_PIXEL_FORMAT_R_8 = 0x10D,
208 HAL_PIXEL_FORMAT_RG_88 = 0x10E,
209 HAL_PIXEL_FORMAT_INTERLACE = 0x180,
210
211};
212
213/* possible formats for 3D content*/
214enum {
215 HAL_NO_3D = 0x0000,
216 HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,
217 HAL_3D_IN_TOP_BOTTOM = 0x20000,
218 HAL_3D_IN_INTERLEAVE = 0x40000,
219 HAL_3D_IN_SIDE_BY_SIDE_R_L = 0x80000,
220 HAL_3D_OUT_SIDE_BY_SIDE = 0x1000,
221 HAL_3D_OUT_TOP_BOTTOM = 0x2000,
222 HAL_3D_OUT_INTERLEAVE = 0x4000,
223 HAL_3D_OUT_MONOSCOPIC = 0x8000
224};
225
226enum {
227 BUFFER_TYPE_UI = 0,
228 BUFFER_TYPE_VIDEO
229};
230
231#if defined(HDMI_DUAL_DISPLAY)
232enum hdmi_mirroring_state {
233 HDMI_NO_MIRRORING,
234 HDMI_UI_MIRRORING,
235 HDMI_ORIGINAL_RESOLUTION_MIRRORING
236};
237#endif
238/*****************************************************************************/
239
240struct private_module_t;
241struct private_handle_t;
242struct PmemAllocator;
243
244struct qbuf_t {
245 buffer_handle_t buf;
246 int idx;
247};
248
249enum buf_state {
250 SUB,
251 REF,
252 AVL
253};
254
255struct avail_t {
256 pthread_mutex_t lock;
257 pthread_cond_t cond;
258#ifdef __cplusplus
259 bool is_avail;
260 buf_state state;
261#endif
262};
263
264struct private_module_t {
265 gralloc_module_t base;
266
267 struct private_handle_t* framebuffer;
268 uint32_t fbFormat;
269 uint32_t flags;
270 uint32_t numBuffers;
271 uint32_t bufferMask;
272 pthread_mutex_t lock;
273 buffer_handle_t currentBuffer;
274
275 struct fb_var_screeninfo info;
276 struct fb_fix_screeninfo finfo;
277 float xdpi;
278 float ydpi;
279 float fps;
280 int swapInterval;
281#ifdef __cplusplus
282 Queue<struct qbuf_t> disp; // non-empty when buffer is ready for display
283#endif
284 int currentIdx;
285 struct avail_t avail[NUM_FRAMEBUFFERS_MAX];
286 pthread_mutex_t qlock;
287 pthread_cond_t qpost;
288
289 enum {
290 // flag to indicate we'll post this buffer
291 PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
292 PRIV_MIN_SWAP_INTERVAL = 0,
293 PRIV_MAX_SWAP_INTERVAL = 1,
294 };
295#if defined(__cplusplus) && defined(HDMI_DUAL_DISPLAY)
296 Overlay* pobjOverlay;
297 int orientation;
298 bool videoOverlay;
299 uint32_t currentOffset;
300 int enableHDMIOutput; // holds the type of external display
301 bool trueMirrorSupport;
302 bool exitHDMIUILoop;
303 float actionsafeWidthRatio;
304 float actionsafeHeightRatio;
305 bool hdmiStateChanged;
306 hdmi_mirroring_state hdmiMirroringState;
307 pthread_mutex_t overlayLock;
308 pthread_cond_t overlayPost;
309#endif
310};
311
312/*****************************************************************************/
313
314#ifdef __cplusplus
315struct private_handle_t : public native_handle {
316#else
317struct private_handle_t {
318 native_handle_t nativeHandle;
319#endif
320 enum {
321 PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
322 PRIV_FLAGS_USES_PMEM = 0x00000002,
323 PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
324 PRIV_FLAGS_USES_ION = 0x00000008,
325 PRIV_FLAGS_USES_ASHMEM = 0x00000010,
326 PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
327 PRIV_FLAGS_DO_NOT_FLUSH = 0x00000040,
328 PRIV_FLAGS_SW_LOCK = 0x00000080,
329 PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
330 PRIV_FLAGS_HWC_LOCK = 0x00000200, // Set by HWC when storing the handle
331 PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
332 PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800, // For explicit synchronization
333 PRIV_FLAGS_NOT_MAPPED = 0x00001000, // Not mapped in userspace
334 PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000, // Display on external only
335 PRIV_FLAGS_EXTERNAL_BLOCK = 0x00004000, // Display only this buffer on external
336 };
337
338 // file-descriptors
339 int fd;
340 int genlockHandle; // genlock handle to be dup'd by the binder
341 // ints
342 int magic;
343 int flags;
344 int size;
345 int offset;
346 int bufferType;
347
348 // FIXME: the attributes below should be out-of-line
349 int base;
350 int gpuaddr; // The gpu address mapped into the mmu. If using ashmem, set to 0 They don't care
351 int pid;
352 int format;
353 int width;
354 int height;
355 int genlockPrivFd; // local fd of the genlock device.
356
357#ifdef __cplusplus
358 static const int sNumInts = 12;
359 static const int sNumFds = 2;
360 static const int sMagic = 'gmsm';
361
362 private_handle_t(int fd, int size, int flags, int bufferType, int format, int width, int height) :
363 fd(fd), genlockHandle(-1), magic(sMagic), flags(flags), size(size), offset(0),
364 bufferType(bufferType), base(0), gpuaddr(0), pid(getpid()), format(format),
365 width(width), height(height), genlockPrivFd(-1)
366 {
367 version = sizeof(native_handle);
368 numInts = sNumInts;
369 numFds = sNumFds;
370 }
371 ~private_handle_t() {
372 magic = 0;
373 }
374
375 bool usesPhysicallyContiguousMemory() {
376 return (flags & PRIV_FLAGS_USES_PMEM) != 0;
377 }
378
379 static int validate(const native_handle* h) {
380 const private_handle_t* hnd = (const private_handle_t*)h;
381 if (!h || h->version != sizeof(native_handle) ||
382 h->numInts != sNumInts || h->numFds != sNumFds ||
383 hnd->magic != sMagic)
384 {
385 ALOGE("invalid gralloc handle (at %p)", h);
386 return -EINVAL;
387 }
388 return 0;
389 }
390
391 static private_handle_t* dynamicCast(const native_handle* in) {
392 if (validate(in) == 0) {
393 return (private_handle_t*) in;
394 }
395 return NULL;
396 }
397#endif
398};
399
400#endif /* GRALLOC_PRIV_H_ */