blob: e6693c9d64fbceb25a30f2fd446d0efdb0cd5897 [file] [log] [blame]
Iliyan Malchev202a77d2012-06-11 14:41:12 -07001/*
Mansoor Aftabe9912a62014-07-15 01:40:26 -07002 * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
Iliyan Malchev202a77d2012-06-11 14:41:12 -07003
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Duy Truong73d36df2013-02-09 20:33:23 -080013 * * Neither the name of The Linux Foundation nor the names of its
Iliyan Malchev202a77d2012-06-11 14:41:12 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <cutils/log.h>
Iliyan Malchev202a77d2012-06-11 14:41:12 -070031#include <fcntl.h>
Naomi Luis01f5c8e2013-02-11 12:46:24 -080032#include <dlfcn.h>
Iliyan Malchev202a77d2012-06-11 14:41:12 -070033#include "gralloc_priv.h"
34#include "alloc_controller.h"
35#include "memalloc.h"
36#include "ionalloc.h"
Iliyan Malchev202a77d2012-06-11 14:41:12 -070037#include "gr.h"
Ramkumar Radhakrishnan29a36a52015-06-16 20:22:42 -070038#include "qd_utils.h"
Kaushik Kanetkar071aca62015-01-22 23:16:26 -070039#include <qdMetaData.h>
Ramkumar Radhakrishnan29a36a52015-06-16 20:22:42 -070040#include <utils/Singleton.h>
41#include <utils/Mutex.h>
42
Iliyan Malchev202a77d2012-06-11 14:41:12 -070043
Sushil Chauhanc6bd6d92012-12-12 12:33:01 -080044#ifdef VENUS_COLOR_FORMAT
45#include <media/msm_media_info.h>
46#else
47#define VENUS_Y_STRIDE(args...) 0
48#define VENUS_Y_SCANLINES(args...) 0
49#define VENUS_BUFFER_SIZE(args...) 0
50#endif
51
Naseer Ahmed63326f42013-12-18 02:45:48 -050052#define ASTC_BLOCK_SIZE 16
Naseer Ahmed63326f42013-12-18 02:45:48 -050053
Shalaj Jain3c490412015-04-22 16:52:03 -070054#ifndef ION_FLAG_CP_PIXEL
Shalaj Jain1f9725a2015-03-04 17:53:49 -080055#define ION_FLAG_CP_PIXEL 0
Shalaj Jain1f9725a2015-03-04 17:53:49 -080056#endif
57
58#ifndef ION_FLAG_ALLOW_NON_CONTIG
59#define ION_FLAG_ALLOW_NON_CONTIG 0
60#endif
61
Shalaj Jain3c490412015-04-22 16:52:03 -070062#ifdef MASTER_SIDE_CP
63#define CP_HEAP_ID ION_SECURE_HEAP_ID
Arun Kumar K.R7f0b24b2015-07-05 21:20:57 -070064#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
Shalaj Jain3c490412015-04-22 16:52:03 -070065#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
Arun Kumar K.R7f0b24b2015-07-05 21:20:57 -070066#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
Shalaj Jain3c490412015-04-22 16:52:03 -070067#else // SLAVE_SIDE_CP
68#define CP_HEAP_ID ION_CP_MM_HEAP_ID
69#define SD_HEAP_ID CP_HEAP_ID
70#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
71#define ION_SD_FLAGS ION_SECURE
72#endif
73
Iliyan Malchev202a77d2012-06-11 14:41:12 -070074using namespace gralloc;
Naseer Ahmeda87da602012-07-01 23:54:19 -070075using namespace qdutils;
Ramkumar Radhakrishnan29a36a52015-06-16 20:22:42 -070076using namespace android;
Iliyan Malchev202a77d2012-06-11 14:41:12 -070077
Naomi Luisa44100c2013-02-08 12:42:03 -080078ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
79
Sushil Chauhan65e26302015-01-14 10:48:57 -080080static void getUBwcWidthAndHeight(int, int, int, int&, int&);
81static unsigned int getUBwcSize(int, int, int, const int, const int);
82
Iliyan Malchev202a77d2012-06-11 14:41:12 -070083//Common functions
Iliyan Malchev202a77d2012-06-11 14:41:12 -070084
Saurabh Shah1adcafe2014-12-19 10:05:41 -080085/* The default policy is to return cached buffers unless the client explicity
86 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
87 * read or written in software. Any combination with a _RARELY_ flag will be
88 * treated as uncached. */
89static bool useUncached(const int& usage) {
90 if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
91 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
92 GRALLOC_USAGE_SW_WRITE_RARELY) or
93 ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
94 GRALLOC_USAGE_SW_READ_RARELY))
95 return true;
96
97 return false;
98}
99
Naomi Luisa44100c2013-02-08 12:42:03 -0800100//-------------- AdrenoMemInfo-----------------------//
Naomi Luis01f5c8e2013-02-11 12:46:24 -0800101AdrenoMemInfo::AdrenoMemInfo()
102{
Ramkumar Radhakrishnan473f4082013-11-04 14:29:18 -0800103 LINK_adreno_compute_aligned_width_and_height = NULL;
104 LINK_adreno_compute_padding = NULL;
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700105 LINK_adreno_isMacroTilingSupportedByGpu = NULL;
Jeykumar Sankaran2ba20512014-02-27 15:21:42 -0800106 LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
Sushil Chauhan082acd62015-01-14 16:49:29 -0800107 LINK_adreno_isUBWCSupportedByGpu = NULL;
Sushil Chauhan521ce352015-08-28 11:33:30 -0700108 LINK_adreno_get_gpu_pixel_alignment = NULL;
Ramkumar Radhakrishnan473f4082013-11-04 14:29:18 -0800109
Naomi Luis01f5c8e2013-02-11 12:46:24 -0800110 libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
111 if (libadreno_utils) {
Ramkumar Radhakrishnan473f4082013-11-04 14:29:18 -0800112 *(void **)&LINK_adreno_compute_aligned_width_and_height =
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700113 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
114 *(void **)&LINK_adreno_compute_padding =
115 ::dlsym(libadreno_utils, "compute_surface_padding");
116 *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
117 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
Jeykumar Sankaran2ba20512014-02-27 15:21:42 -0800118 *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
119 ::dlsym(libadreno_utils,
120 "compute_compressedfmt_aligned_width_and_height");
Sushil Chauhan082acd62015-01-14 16:49:29 -0800121 *(void **)&LINK_adreno_isUBWCSupportedByGpu =
122 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
Sushil Chauhan521ce352015-08-28 11:33:30 -0700123 *(void **)&LINK_adreno_get_gpu_pixel_alignment =
124 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
Naomi Luis01f5c8e2013-02-11 12:46:24 -0800125 }
Mohan Maiyacbeab9e2015-04-20 09:20:44 -0700126
127 // Check if the overriding property debug.gralloc.gfx_ubwc_disable
128 // that disables UBWC allocations for the graphics stack is set
129 gfx_ubwc_disable = 0;
130 char property[PROPERTY_VALUE_MAX];
131 property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
132 if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
133 !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
134 gfx_ubwc_disable = 1;
135 }
Naomi Luis01f5c8e2013-02-11 12:46:24 -0800136}
137
138AdrenoMemInfo::~AdrenoMemInfo()
139{
140 if (libadreno_utils) {
141 ::dlclose(libadreno_utils);
142 }
143}
144
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700145int AdrenoMemInfo::isMacroTilingSupportedByGPU()
146{
147 if ((libadreno_utils)) {
148 if(LINK_adreno_isMacroTilingSupportedByGpu) {
149 return LINK_adreno_isMacroTilingSupportedByGpu();
150 }
151 }
152 return 0;
153}
154
Manoj Kumar AVM8e1aa182015-08-05 19:45:16 -0700155void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
156 int& aligned_h) {
157 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
158 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
159 int w = metadata->bufferDim.sliceWidth;
160 int h = metadata->bufferDim.sliceHeight;
161 int f = hnd->format;
162 int usage = 0;
163
164 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
165 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
166 }
167
168 getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
169 } else {
170 aligned_w = hnd->width;
171 aligned_h = hnd->height;
172 }
173
174}
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700175
Naomi Luiscffc5bd2015-08-28 14:57:31 -0700176bool isUncompressedRgbFormat(int format)
177{
178 bool is_rgb_format = false;
179
180 switch (format)
181 {
182 case HAL_PIXEL_FORMAT_RGBA_8888:
183 case HAL_PIXEL_FORMAT_RGBX_8888:
184 case HAL_PIXEL_FORMAT_RGB_888:
185 case HAL_PIXEL_FORMAT_RGB_565:
186 case HAL_PIXEL_FORMAT_BGRA_8888:
187 case HAL_PIXEL_FORMAT_RGBA_5551:
188 case HAL_PIXEL_FORMAT_RGBA_4444:
189 case HAL_PIXEL_FORMAT_R_8:
190 case HAL_PIXEL_FORMAT_RG_88:
191 case HAL_PIXEL_FORMAT_BGRX_8888: // Intentional fallthrough
192 is_rgb_format = true;
193 break;
194 default:
195 break;
196 }
197
198 return is_rgb_format;
199}
200
Ramkumar Radhakrishnan473f4082013-11-04 14:29:18 -0800201void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
Sushil Chauhan65e26302015-01-14 10:48:57 -0800202 int usage, int& aligned_w, int& aligned_h)
Naomi Luisa44100c2013-02-08 12:42:03 -0800203{
Sushil Chauhane61fac52015-04-30 17:14:37 -0700204 bool ubwc_enabled = isUBwcEnabled(format, usage);
205
Naomi Luis01f5c8e2013-02-11 12:46:24 -0800206 // Currently surface padding is only computed for RGB* surfaces.
Naomi Luiscffc5bd2015-08-28 14:57:31 -0700207 if (isUncompressedRgbFormat(format) == true) {
Sushil Chauhane61fac52015-04-30 17:14:37 -0700208 int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
Manoj Kumar AVM8e1aa182015-08-05 19:45:16 -0700209 getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
Sushil Chauhan65e26302015-01-14 10:48:57 -0800210 return;
Naomi Luisa44100c2013-02-08 12:42:03 -0800211 }
Sushil Chauhan65e26302015-01-14 10:48:57 -0800212
Sushil Chauhane61fac52015-04-30 17:14:37 -0700213 if (ubwc_enabled) {
Sushil Chauhan65e26302015-01-14 10:48:57 -0800214 getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
215 return;
216 }
217
218 aligned_w = width;
219 aligned_h = height;
Sushil Chauhan521ce352015-08-28 11:33:30 -0700220 int alignment = 32;
Sushil Chauhan65e26302015-01-14 10:48:57 -0800221 switch (format)
222 {
223 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Sushil Chauhan521ce352015-08-28 11:33:30 -0700224 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
225 if (LINK_adreno_get_gpu_pixel_alignment) {
226 alignment = LINK_adreno_get_gpu_pixel_alignment();
227 }
228 aligned_w = ALIGN(width, alignment);
229 break;
Sushil Chauhan65e26302015-01-14 10:48:57 -0800230 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
Sushil Chauhan521ce352015-08-28 11:33:30 -0700231 aligned_w = ALIGN(width, alignment);
Sushil Chauhan65e26302015-01-14 10:48:57 -0800232 break;
Ajay Dudani4dc06492015-03-26 07:28:11 -0700233 case HAL_PIXEL_FORMAT_RAW16:
Shuzhen Wang2a000b22014-08-20 00:15:51 -0700234 aligned_w = ALIGN(width, 16);
235 break;
Mansoor Aftabe9912a62014-07-15 01:40:26 -0700236 case HAL_PIXEL_FORMAT_RAW10:
237 aligned_w = ALIGN(width * 10 /8, 16);
238 break;
Sushil Chauhan65e26302015-01-14 10:48:57 -0800239 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
240 aligned_w = ALIGN(width, 128);
241 break;
Sushil Chauhan65e26302015-01-14 10:48:57 -0800242 case HAL_PIXEL_FORMAT_YV12:
243 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
244 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
245 case HAL_PIXEL_FORMAT_YCbCr_422_I:
246 case HAL_PIXEL_FORMAT_YCrCb_422_I:
247 aligned_w = ALIGN(width, 16);
248 break;
249 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
250 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
251 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
252 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
253 break;
Raj Kamal8bb3b8f2015-03-24 16:22:17 +0530254 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
255 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
256 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
257 break;
Sushil Chauhan65e26302015-01-14 10:48:57 -0800258 case HAL_PIXEL_FORMAT_BLOB:
259 break;
260 case HAL_PIXEL_FORMAT_NV21_ZSL:
261 aligned_w = ALIGN(width, 64);
262 aligned_h = ALIGN(height, 64);
263 break;
264 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
265 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
266 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
267 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
268 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
269 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
270 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
271 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
272 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
273 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
274 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
275 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
276 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
277 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
278 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
279 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
280 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
281 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
282 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
283 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
284 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
285 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
286 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
287 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
288 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
289 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
290 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
291 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
292 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
293 int bytesPerPixel = 0;
294 int raster_mode = 0; //Adreno unknown raster mode.
295 int padding_threshold = 512; //Threshold for padding
296 //surfaces.
297
298 LINK_adreno_compute_compressedfmt_aligned_width_and_height(
299 width, height, format, 0,raster_mode, padding_threshold,
300 &aligned_w, &aligned_h, &bytesPerPixel);
301 } else {
302 ALOGW("%s: Warning!! Symbols" \
303 " compute_compressedfmt_aligned_width_and_height" \
304 " not found", __FUNCTION__);
305 }
306 break;
307 default: break;
308 }
309}
310
311void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
312 int tile_enabled, int& aligned_w, int& aligned_h)
313{
314 aligned_w = ALIGN(width, 32);
315 aligned_h = ALIGN(height, 32);
316
317 // Don't add any additional padding if debug.gralloc.map_fb_memory
318 // is enabled
319 char property[PROPERTY_VALUE_MAX];
320 if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
321 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
322 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
323 return;
324 }
325
326 int bpp = 4;
327 switch(format)
328 {
329 case HAL_PIXEL_FORMAT_RGB_888:
330 bpp = 3;
331 break;
332 case HAL_PIXEL_FORMAT_RGB_565:
333 case HAL_PIXEL_FORMAT_RGBA_5551:
334 case HAL_PIXEL_FORMAT_RGBA_4444:
335 bpp = 2;
336 break;
337 default: break;
338 }
339
340 if (libadreno_utils) {
341 int raster_mode = 0; // Adreno unknown raster mode.
342 int padding_threshold = 512; // Threshold for padding surfaces.
343 // the function below computes aligned width and aligned height
344 // based on linear or macro tile mode selected.
345 if(LINK_adreno_compute_aligned_width_and_height) {
346 LINK_adreno_compute_aligned_width_and_height(width,
347 height, bpp, tile_enabled,
348 raster_mode, padding_threshold,
349 &aligned_w, &aligned_h);
350
351 } else if(LINK_adreno_compute_padding) {
352 int surface_tile_height = 1; // Linear surface
353 aligned_w = LINK_adreno_compute_padding(width, bpp,
354 surface_tile_height, raster_mode,
355 padding_threshold);
356 ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
357 __FUNCTION__);
358 } else {
359 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
360 "compute_aligned_width_and_height not found", __FUNCTION__);
361 }
362 }
363}
364
365int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
366{
Mohan Maiyacbeab9e2015-04-20 09:20:44 -0700367 if (!gfx_ubwc_disable && libadreno_utils) {
Sushil Chauhan082acd62015-01-14 16:49:29 -0800368 if (LINK_adreno_isUBWCSupportedByGpu) {
369 ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
370 return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
371 }
372 }
Sushil Chauhan65e26302015-01-14 10:48:57 -0800373 return 0;
Naomi Luisa44100c2013-02-08 12:42:03 -0800374}
375
Sushil Chauhan082acd62015-01-14 16:49:29 -0800376ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
377{
378 switch (hal_format) {
379 case HAL_PIXEL_FORMAT_RGBA_8888:
380 return ADRENO_PIXELFORMAT_R8G8B8A8;
Sushil Chauhan6686c802015-04-15 11:30:39 -0700381 case HAL_PIXEL_FORMAT_RGBX_8888:
382 return ADRENO_PIXELFORMAT_R8G8B8X8;
Sushil Chauhan082acd62015-01-14 16:49:29 -0800383 case HAL_PIXEL_FORMAT_RGB_565:
384 return ADRENO_PIXELFORMAT_B5G6R5;
Sushil Chauhan082acd62015-01-14 16:49:29 -0800385 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
Sushil Chauhana9d47002015-02-18 14:55:03 -0800386 return ADRENO_PIXELFORMAT_NV12;
Sushil Chauhan082acd62015-01-14 16:49:29 -0800387 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
388 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
Sushil Chauhana9d47002015-02-18 14:55:03 -0800389 return ADRENO_PIXELFORMAT_NV12_EXT;
Sushil Chauhan082acd62015-01-14 16:49:29 -0800390 default:
391 ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
392 break;
393 }
394 return ADRENO_PIXELFORMAT_UNKNOWN;
395}
396
Naomi Luisa44100c2013-02-08 12:42:03 -0800397//-------------- IAllocController-----------------------//
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700398IAllocController* IAllocController::sController = NULL;
399IAllocController* IAllocController::getInstance(void)
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700400{
401 if(sController == NULL) {
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700402 sController = new IonController();
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700403 }
404 return sController;
405}
406
407
408//-------------- IonController-----------------------//
409IonController::IonController()
410{
Praveena Pachipulusu2005e8f2014-05-07 20:01:54 +0530411 allocateIonMem();
412}
413
414void IonController::allocateIonMem()
415{
416 mIonAlloc = new IonAlloc();
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700417}
418
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700419int IonController::allocate(alloc_data& data, int usage)
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700420{
421 int ionFlags = 0;
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500422 int ionHeapId = 0;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700423 int ret;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700424
425 data.uncached = useUncached(usage);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700426 data.allocType = 0;
427
Prabhanjan Kandula92896b82013-05-07 19:58:24 +0530428 if(usage & GRALLOC_USAGE_PROTECTED) {
Prabhanjan Kandulae8f4bec2013-10-24 16:32:51 +0530429 if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
Shalaj Jain1f9725a2015-03-04 17:53:49 -0800430 if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
Shalaj Jain3c490412015-04-22 16:52:03 -0700431 ionHeapId = ION_HEAP(SD_HEAP_ID);
Shalaj Jain1f9725a2015-03-04 17:53:49 -0800432 /*
433 * There is currently no flag in ION for Secure Display
Shalaj Jain3c490412015-04-22 16:52:03 -0700434 * VM. Please add it to the define once available.
Shalaj Jain1f9725a2015-03-04 17:53:49 -0800435 */
Shalaj Jain3c490412015-04-22 16:52:03 -0700436 ionFlags |= ION_SD_FLAGS;
Shalaj Jain1f9725a2015-03-04 17:53:49 -0800437 } else {
Shalaj Jain3c490412015-04-22 16:52:03 -0700438 ionHeapId = ION_HEAP(CP_HEAP_ID);
439 ionFlags |= ION_CP_FLAGS;
Shalaj Jain13cdf812014-12-02 16:20:54 -0800440 }
Prabhanjan Kandula92896b82013-05-07 19:58:24 +0530441 } else {
442 // for targets/OEMs which do not need HW level protection
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500443 // do not set ion secure flag & MM heap. Fallback to system heap.
444 ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
Justin Philipd6166602014-08-12 13:42:21 +0530445 data.allocType |= private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER;
Naseer Ahmedc5e6fb02013-03-07 13:42:20 -0500446 }
Prabhanjan Kandula92896b82013-05-07 19:58:24 +0530447 } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
448 //MM Heap is exclusively a secure heap.
449 //If it is used for non secure cases, fallback to IOMMU heap
450 ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
451 cannot be used as an insecure heap!\
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500452 trying to use system heap instead !!");
453 ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
Naseer Ahmedc5e6fb02013-03-07 13:42:20 -0500454 }
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700455
Arun Kumar K.Rff78b892013-05-24 12:37:51 -0700456 if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500457 ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
Arun Kumar K.Rff78b892013-05-24 12:37:51 -0700458
Arun Kumar K.R0daaa992013-03-12 15:08:29 -0700459 if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500460 ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700461
Prabhanjan Kandula92896b82013-05-07 19:58:24 +0530462 if(ionFlags & ION_SECURE)
Naseer Ahmedc5e6fb02013-03-07 13:42:20 -0500463 data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700464
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500465 // if no ion heap flags are set, default to system heap
466 if(!ionHeapId)
467 ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700468
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500469 //At this point we should have the right heap set, there is no fallback
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700470 data.flags = ionFlags;
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500471 data.heapId = ionHeapId;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700472 ret = mIonAlloc->alloc_buffer(data);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700473
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700474 if(ret >= 0 ) {
Naseer Ahmed29a26812012-06-14 00:56:20 -0700475 data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
Naseer Ahmed8d0d72a2014-12-19 16:25:09 -0500476 } else {
477 ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
478 __FUNCTION__, ionHeapId, ionFlags);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700479 }
480
481 return ret;
482}
483
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700484IMemAlloc* IonController::getAllocator(int flags)
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700485{
Naseer Ahmedb16edac2012-07-15 23:56:21 -0700486 IMemAlloc* memalloc = NULL;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700487 if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
488 memalloc = mIonAlloc;
489 } else {
490 ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
491 }
492
493 return memalloc;
494}
495
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700496bool isMacroTileEnabled(int format, int usage)
497{
498 bool tileEnabled = false;
Ramkumar Radhakrishnan29a36a52015-06-16 20:22:42 -0700499 int isMacroTileSupportedByMDP = 0;
500
501 qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupportedByMDP);
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700502
503 // Check whether GPU & MDSS supports MacroTiling feature
504 if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
Ramkumar Radhakrishnan29a36a52015-06-16 20:22:42 -0700505 isMacroTileSupportedByMDP)
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700506 {
507 // check the format
508 switch(format)
509 {
510 case HAL_PIXEL_FORMAT_RGBA_8888:
511 case HAL_PIXEL_FORMAT_RGBX_8888:
512 case HAL_PIXEL_FORMAT_BGRA_8888:
Manoj Kumar AVM5a5529b2014-02-24 18:16:37 -0800513 case HAL_PIXEL_FORMAT_RGB_565:
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700514 {
515 tileEnabled = true;
516 // check the usage flags
517 if (usage & (GRALLOC_USAGE_SW_READ_MASK |
518 GRALLOC_USAGE_SW_WRITE_MASK)) {
519 // Application intends to use CPU for rendering
520 tileEnabled = false;
521 }
522 break;
523 }
524 default:
525 break;
526 }
527 }
528 return tileEnabled;
529}
530
531// helper function
Sushil Chauhan65e26302015-01-14 10:48:57 -0800532unsigned int getSize(int format, int width, int height, int usage,
533 const int alignedw, const int alignedh) {
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700534
Sushil Chauhan65e26302015-01-14 10:48:57 -0800535 if (isUBwcEnabled(format, usage)) {
536 return getUBwcSize(width, height, format, alignedw, alignedh);
537 }
538
539 unsigned int size = 0;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700540 switch (format) {
541 case HAL_PIXEL_FORMAT_RGBA_8888:
542 case HAL_PIXEL_FORMAT_RGBX_8888:
543 case HAL_PIXEL_FORMAT_BGRA_8888:
544 size = alignedw * alignedh * 4;
545 break;
546 case HAL_PIXEL_FORMAT_RGB_888:
547 size = alignedw * alignedh * 3;
548 break;
549 case HAL_PIXEL_FORMAT_RGB_565:
Ramkumar Radhakrishnan96439522014-10-09 13:37:52 -0700550 case HAL_PIXEL_FORMAT_RGBA_5551:
551 case HAL_PIXEL_FORMAT_RGBA_4444:
Ajay Dudani4dc06492015-03-26 07:28:11 -0700552 case HAL_PIXEL_FORMAT_RAW16:
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700553 size = alignedw * alignedh * 2;
554 break;
Mansoor Aftabe9912a62014-07-15 01:40:26 -0700555 case HAL_PIXEL_FORMAT_RAW10:
556 size = ALIGN(alignedw * alignedh, 4096);
557 break;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700558
559 // adreno formats
560 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
561 size = ALIGN(alignedw*alignedh, 4096);
562 size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
563 break;
564 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
565 // The chroma plane is subsampled,
566 // but the pitch in bytes is unchanged
567 // The GPU needs 4K alignment, but the video decoder needs 8K
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700568 size = ALIGN( alignedw * alignedh, 8192);
569 size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
570 break;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700571 case HAL_PIXEL_FORMAT_YV12:
572 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
573 ALOGE("w or h is odd for the YV12 format");
Saurabh Shahd0b0d8f2014-01-31 11:45:56 -0800574 return 0;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700575 }
Naseer Ahmedce0c9502013-08-15 13:07:24 -0400576 size = alignedw*alignedh +
Naseer Ahmed29a26812012-06-14 00:56:20 -0700577 (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700578 size = ALIGN(size, (unsigned int)4096);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700579 break;
Ramkumar Radhakrishnan73f952a2013-03-05 14:14:24 -0800580 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
581 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
Naseer Ahmed2c215292013-09-18 23:47:42 -0400582 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
Ramkumar Radhakrishnan73f952a2013-03-05 14:14:24 -0800583 break;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700584 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
585 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
Ramkumar Radhakrishnanb52399c2013-08-06 20:17:29 -0700586 case HAL_PIXEL_FORMAT_YCbCr_422_I:
587 case HAL_PIXEL_FORMAT_YCrCb_422_I:
Naseer Ahmed29a26812012-06-14 00:56:20 -0700588 if(width & 1) {
589 ALOGE("width is odd for the YUV422_SP format");
Saurabh Shahd0b0d8f2014-01-31 11:45:56 -0800590 return 0;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700591 }
Naseer Ahmed29a26812012-06-14 00:56:20 -0700592 size = ALIGN(alignedw * alignedh * 2, 4096);
593 break;
Sushil Chauhanc5e61482012-08-22 17:13:32 -0700594 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
Naseer Ahmedce0c9502013-08-15 13:07:24 -0400595 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
Sushil Chauhane8a01792012-11-01 16:25:45 -0700596 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
Sushil Chauhanc5e61482012-08-22 17:13:32 -0700597 break;
Raj Kamal8bb3b8f2015-03-24 16:22:17 +0530598 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
599 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
600 break;
Naseer Ahmed7669dae2013-04-17 20:23:53 -0400601 case HAL_PIXEL_FORMAT_BLOB:
602 if(height != 1) {
603 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
604 must have height==1 ", __FUNCTION__);
Saurabh Shahd0b0d8f2014-01-31 11:45:56 -0800605 return 0;
Naseer Ahmed7669dae2013-04-17 20:23:53 -0400606 }
Naseer Ahmed7669dae2013-04-17 20:23:53 -0400607 size = width;
608 break;
Ramkumar Radhakrishnanff511022013-07-23 16:12:08 -0700609 case HAL_PIXEL_FORMAT_NV21_ZSL:
Ramkumar Radhakrishnanff511022013-07-23 16:12:08 -0700610 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
611 break;
Naseer Ahmed63326f42013-12-18 02:45:48 -0500612 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
613 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
614 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
615 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
616 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
617 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
618 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
619 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
620 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
621 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
622 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
623 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
624 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
625 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
626 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
627 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
628 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
629 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
630 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
631 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
632 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
633 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
634 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
635 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
636 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
637 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
638 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
Jeykumar Sankaran8f4585f2014-02-05 15:23:40 -0800639 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
Naseer Ahmed63326f42013-12-18 02:45:48 -0500640 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
641 break;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700642 default:
Sushil Chauhan65e26302015-01-14 10:48:57 -0800643 ALOGE("Unrecognized pixel format: 0x%x", __FUNCTION__, format);
Saurabh Shahd0b0d8f2014-01-31 11:45:56 -0800644 return 0;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700645 }
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700646 return size;
647}
648
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700649unsigned int getBufferSizeAndDimensions(int width, int height, int format,
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700650 int& alignedw, int &alignedh)
651{
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700652 unsigned int size;
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700653
654 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
655 height,
656 format,
Sushil Chauhan65e26302015-01-14 10:48:57 -0800657 0,
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700658 alignedw,
659 alignedh);
660
Sushil Chauhan65e26302015-01-14 10:48:57 -0800661 size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700662
663 return size;
664}
665
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700666
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700667unsigned int getBufferSizeAndDimensions(int width, int height, int format,
668 int usage, int& alignedw, int &alignedh)
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700669{
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700670 unsigned int size;
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700671
672 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
673 height,
674 format,
Sushil Chauhan65e26302015-01-14 10:48:57 -0800675 usage,
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700676 alignedw,
677 alignedh);
678
Sushil Chauhan65e26302015-01-14 10:48:57 -0800679 size = getSize(format, width, height, usage, alignedw, alignedh);
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700680
681 return size;
682}
683
684
685void getBufferAttributes(int width, int height, int format, int usage,
Sushil Chauhane61fac52015-04-30 17:14:37 -0700686 int& alignedw, int &alignedh, int& tiled, unsigned int& size)
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700687{
Sushil Chauhane61fac52015-04-30 17:14:37 -0700688 tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700689
690 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
691 height,
692 format,
Sushil Chauhan65e26302015-01-14 10:48:57 -0800693 usage,
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700694 alignedw,
695 alignedh);
Sushil Chauhan65e26302015-01-14 10:48:57 -0800696 size = getSize(format, width, height, usage, alignedw, alignedh);
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700697}
698
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400699int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
700{
701 int err = 0;
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700702 int width = hnd->width;
703 int height = hnd->height;
Sushil Chauhane7acc3c2015-06-23 16:22:30 -0700704 int format = hnd->format;
Manoj Kumar AVM8e1aa182015-08-05 19:45:16 -0700705
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700706 unsigned int ystride, cstride;
Sushil Chauhan4686c972015-02-20 15:44:52 -0800707 unsigned int alignment = 4096;
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700708
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400709 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
Sushil Chauhane7acc3c2015-06-23 16:22:30 -0700710 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
711
712 // Check if UBWC buffer has been rendered in linear format.
713 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
714 format = metadata->linearFormat;
715 }
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400716
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700717 // Check metadata if the geometry has been updated.
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700718 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
Manoj Kumar AVM8e1aa182015-08-05 19:45:16 -0700719 int usage = 0;
720
721 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
722 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
723 }
724
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700725 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
Manoj Kumar AVM8e1aa182015-08-05 19:45:16 -0700726 metadata->bufferDim.sliceHeight, format, usage, width, height);
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700727 }
728
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400729 // Get the chroma offsets from the handle width/height. We take advantage
730 // of the fact the width _is_ the stride
Sushil Chauhane7acc3c2015-06-23 16:22:30 -0700731 switch (format) {
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400732 //Semiplanar
733 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
734 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
735 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
736 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700737 ystride = cstride = width;
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400738 ycbcr->y = (void*)hnd->base;
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700739 ycbcr->cb = (void*)(hnd->base + ystride * height);
740 ycbcr->cr = (void*)(hnd->base + ystride * height + 1);
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400741 ycbcr->ystride = ystride;
742 ycbcr->cstride = cstride;
743 ycbcr->chroma_step = 2;
744 break;
745
Sushil Chauhan4686c972015-02-20 15:44:52 -0800746 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
747 // NV12_UBWC buffer has these 4 planes in the following sequence:
748 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
749 unsigned int y_meta_stride, y_meta_height, y_meta_size;
750 unsigned int y_stride, y_height, y_size;
751 unsigned int c_meta_stride, c_meta_height, c_meta_size;
752
753 y_meta_stride = VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, width);
754 y_meta_height = VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, height);
755 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
756
757 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
758 y_height = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
759 y_size = ALIGN((y_stride * y_height), alignment);
760
761 c_meta_stride = VENUS_UV_META_STRIDE(COLOR_FMT_NV12_UBWC, width);
762 c_meta_height = VENUS_UV_META_SCANLINES(COLOR_FMT_NV12_UBWC, height);
763 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
764
765 ycbcr->y = (void*)(hnd->base + y_meta_size);
766 ycbcr->cb = (void*)(hnd->base + y_meta_size + y_size + c_meta_size);
767 ycbcr->cr = (void*)(hnd->base + y_meta_size + y_size +
768 c_meta_size + 1);
769 ycbcr->ystride = y_stride;
770 ycbcr->cstride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, width);
771 ycbcr->chroma_step = 2;
772 break;
773
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400774 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
775 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
776 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
Raj Kamal8bb3b8f2015-03-24 16:22:17 +0530777 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400778 case HAL_PIXEL_FORMAT_NV21_ZSL:
Ajay Dudani4dc06492015-03-26 07:28:11 -0700779 case HAL_PIXEL_FORMAT_RAW16:
Mansoor Aftabe9912a62014-07-15 01:40:26 -0700780 case HAL_PIXEL_FORMAT_RAW10:
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700781 ystride = cstride = width;
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400782 ycbcr->y = (void*)hnd->base;
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700783 ycbcr->cr = (void*)(hnd->base + ystride * height);
784 ycbcr->cb = (void*)(hnd->base + ystride * height + 1);
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400785 ycbcr->ystride = ystride;
786 ycbcr->cstride = cstride;
787 ycbcr->chroma_step = 2;
788 break;
789
790 //Planar
791 case HAL_PIXEL_FORMAT_YV12:
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700792 ystride = width;
793 cstride = ALIGN(width/2, 16);
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400794 ycbcr->y = (void*)hnd->base;
Kaushik Kanetkar071aca62015-01-22 23:16:26 -0700795 ycbcr->cr = (void*)(hnd->base + ystride * height);
796 ycbcr->cb = (void*)(hnd->base + ystride * height +
797 cstride * height/2);
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400798 ycbcr->ystride = ystride;
799 ycbcr->cstride = cstride;
800 ycbcr->chroma_step = 1;
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400801 break;
802 //Unsupported formats
803 case HAL_PIXEL_FORMAT_YCbCr_422_I:
804 case HAL_PIXEL_FORMAT_YCrCb_422_I:
805 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
806 default:
Sushil Chauhane7acc3c2015-06-23 16:22:30 -0700807 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
Naseer Ahmedb29fdfd2014-04-08 20:23:47 -0400808 err = -EINVAL;
809 }
810 return err;
811
812}
813
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700814
815
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700816// Allocate buffer from width, height and format into a
817// private_handle_t. It is the responsibility of the caller
818// to free the buffer using the free_buffer function
819int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
820{
Naseer Ahmed29a26812012-06-14 00:56:20 -0700821 alloc_data data;
822 int alignedw, alignedh;
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700823 gralloc::IAllocController* sAlloc =
824 gralloc::IAllocController::getInstance();
Naseer Ahmed29a26812012-06-14 00:56:20 -0700825 data.base = 0;
826 data.fd = -1;
827 data.offset = 0;
Manoj Kumar AVM8a220812013-10-10 11:46:06 -0700828 data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
829 alignedh);
830
Naseer Ahmed29a26812012-06-14 00:56:20 -0700831 data.align = getpagesize();
832 data.uncached = useUncached(usage);
833 int allocFlags = usage;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700834
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700835 int err = sAlloc->allocate(data, allocFlags);
Naseer Ahmed29a26812012-06-14 00:56:20 -0700836 if (0 != err) {
837 ALOGE("%s: allocate failed", __FUNCTION__);
838 return -ENOMEM;
839 }
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700840
Naseer Ahmed29a26812012-06-14 00:56:20 -0700841 private_handle_t* hnd = new private_handle_t(data.fd, data.size,
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700842 data.allocType, 0, format,
843 alignedw, alignedh);
Saurabh Shah8f0ea6f2014-05-19 16:48:53 -0700844 hnd->base = (uint64_t) data.base;
Naseer Ahmed29a26812012-06-14 00:56:20 -0700845 hnd->offset = data.offset;
846 hnd->gpuaddr = 0;
847 *pHnd = hnd;
848 return 0;
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700849}
850
851void free_buffer(private_handle_t *hnd)
852{
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700853 gralloc::IAllocController* sAlloc =
854 gralloc::IAllocController::getInstance();
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700855 if (hnd && hnd->fd > 0) {
Naseer Ahmed01d3fd32012-07-14 21:08:13 -0700856 IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
Iliyan Malchev202a77d2012-06-11 14:41:12 -0700857 memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
858 }
859 if(hnd)
860 delete hnd;
861
862}
Sushil Chauhan65e26302015-01-14 10:48:57 -0800863
864// UBWC helper functions
865static bool isUBwcFormat(int format)
866{
867 // Explicitly defined UBWC formats
868 switch(format)
869 {
870 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
871 return true;
872 default:
873 return false;
874 }
875}
876
877static bool isUBwcSupported(int format)
878{
879 // Existing HAL formats with UBWC support
880 switch(format)
881 {
882 case HAL_PIXEL_FORMAT_RGB_565:
883 case HAL_PIXEL_FORMAT_RGBA_8888:
Sushil Chauhan6686c802015-04-15 11:30:39 -0700884 case HAL_PIXEL_FORMAT_RGBX_8888:
Sushil Chauhan65e26302015-01-14 10:48:57 -0800885 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
886 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
887 return true;
888 default:
889 return false;
890 }
891}
892
893bool isUBwcEnabled(int format, int usage)
894{
Sushil Chauhan81594f62015-01-26 16:00:51 -0800895 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
896 if (isUBwcFormat(format))
897 return true;
898
Sushil Chauhan7807d192015-08-13 10:10:48 -0700899 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
900 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
901 // usage flag and MDP supports the format.
902 if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
903 bool enable = true;
904 // Query GPU for UBWC only if buffer is intended to be used by GPU.
905 if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
906 enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
907 }
Sushil Chauhan81594f62015-01-26 16:00:51 -0800908 // Allow UBWC, only if CPU usage flags are not set
Sushil Chauhan7807d192015-08-13 10:10:48 -0700909 if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
910 GRALLOC_USAGE_SW_WRITE_MASK))) {
Sushil Chauhan65e26302015-01-14 10:48:57 -0800911 return true;
912 }
913 }
914 return false;
915}
916
917static void getUBwcWidthAndHeight(int width, int height, int format,
918 int& aligned_w, int& aligned_h)
919{
920 switch (format)
921 {
922 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
923 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
924 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
925 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
926 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
927 break;
928 default:
929 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
930 aligned_w = 0;
931 aligned_h = 0;
932 break;
933 }
934}
935
936static void getUBwcBlockSize(int bpp, int& block_width, int& block_height)
937{
938 block_width = 0;
939 block_height = 0;
940
941 switch(bpp)
942 {
943 case 2:
944 case 4:
945 block_width = 16;
946 block_height = 4;
947 break;
948 case 8:
949 block_width = 8;
950 block_height = 4;
951 break;
952 case 16:
953 block_width = 4;
954 block_height = 4;
955 break;
956 default:
957 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
958 break;
959 }
960}
961
962static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp)
963{
964 unsigned int size = 0;
965 int meta_width, meta_height;
966 int block_width, block_height;
967
968 getUBwcBlockSize(bpp, block_width, block_height);
969
970 if (!block_width || !block_height) {
971 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
972 return size;
973 }
974
975 // Align meta buffer height to 16 blocks
976 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
977
978 // Align meta buffer width to 64 blocks
979 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
980
981 // Align meta buffer size to 4K
Sushil Chauhanc85b65b2015-04-30 11:05:36 -0700982 size = ALIGN((meta_width * meta_height), 4096);
Sushil Chauhan65e26302015-01-14 10:48:57 -0800983 return size;
984}
985
986static unsigned int getUBwcSize(int width, int height, int format,
987 const int alignedw, const int alignedh) {
988
989 unsigned int size = 0;
990 switch (format) {
991 case HAL_PIXEL_FORMAT_RGB_565:
992 size = alignedw * alignedh * 2;
993 size += getUBwcMetaBufferSize(width, height, 2);
994 break;
995 case HAL_PIXEL_FORMAT_RGBA_8888:
Sushil Chauhan6686c802015-04-15 11:30:39 -0700996 case HAL_PIXEL_FORMAT_RGBX_8888:
Sushil Chauhan65e26302015-01-14 10:48:57 -0800997 size = alignedw * alignedh * 4;
998 size += getUBwcMetaBufferSize(width, height, 4);
999 break;
1000 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1001 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1002 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1003 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
1004 break;
1005 default:
1006 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
1007 break;
1008 }
1009 return size;
1010}
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001011
Sushil Chauhanc85b65b2015-04-30 11:05:36 -07001012int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001013{
1014 int err = 0;
1015
1016 // This api is for RGB* formats
Ajay Dudani4dc06492015-03-26 07:28:11 -07001017 if (hnd->format > HAL_PIXEL_FORMAT_BGRA_8888) {
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001018 return -EINVAL;
1019 }
1020
1021 // linear buffer
1022 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
Sushil Chauhanc85b65b2015-04-30 11:05:36 -07001023 *rgb_data = (void*)hnd->base;
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001024 return err;
1025 }
1026
1027 unsigned int meta_size = 0;
1028 switch (hnd->format) {
1029 case HAL_PIXEL_FORMAT_RGB_565:
1030 meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 2);
1031 break;
1032 case HAL_PIXEL_FORMAT_RGBA_8888:
1033 case HAL_PIXEL_FORMAT_RGBX_8888:
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001034 meta_size = getUBwcMetaBufferSize(hnd->width, hnd->height, 4);
1035 break;
1036 default:
1037 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
1038 err = -EINVAL;
1039 break;
1040 }
1041
Sushil Chauhanc85b65b2015-04-30 11:05:36 -07001042 *rgb_data = (void*)(hnd->base + meta_size);
Sushil Chauhan7dd3a432015-04-08 15:54:42 -07001043 return err;
1044}