1 /*
2  * Copyright (c) 2011 - 2017, The Linux Foundation. All rights reserved.
3 
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.
13  *   * Neither the name of The Linux Foundation nor the names of its
14  *     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>
31 #include <fcntl.h>
32 #include <dlfcn.h>
33 #include <media/msm_media_info.h>
34 #include <qdMetaData.h>
35 #include <utils/Singleton.h>
36 #include <utils/Mutex.h>
37 #include <algorithm>
38 
39 #include "gralloc_priv.h"
40 #include "alloc_controller.h"
41 #include "memalloc.h"
42 #include "ionalloc.h"
43 #include "gr.h"
44 #include "qd_utils.h"
45 
46 #define ASTC_BLOCK_SIZE 16
47 
48 #ifndef ION_FLAG_CP_PIXEL
49 #define ION_FLAG_CP_PIXEL 0
50 #endif
51 
52 #ifndef ION_FLAG_ALLOW_NON_CONTIG
53 #define ION_FLAG_ALLOW_NON_CONTIG 0
54 #endif
55 
56 #ifndef ION_FLAG_CP_CAMERA_PREVIEW
57 #define ION_FLAG_CP_CAMERA_PREVIEW 0
58 #endif
59 
60 #ifdef MASTER_SIDE_CP
61 #define CP_HEAP_ID ION_SECURE_HEAP_ID
62 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
63 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
64 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
65 #define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
66 #define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
67 #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 #define ION_SC_FLAGS ION_SECURE
73 #define ION_SC_PREVIEW_FLAGS ION_SECURE
74 #endif
75 
76 #ifndef COLOR_FMT_P010_UBWC
77 #define COLOR_FMT_P010_UBWC 9
78 #endif
79 
80 using namespace gralloc;
81 using namespace qdutils;
82 using namespace android;
83 
84 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
85 ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
86 
87 static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
88 static unsigned int getUBwcSize(int, int, int, const int, const int);
89 
90 //Common functions
91 
92 /* The default policy is to return cached buffers unless the client explicity
93  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
94  * read or written in software. Any combination with a _RARELY_ flag will be
95  * treated as uncached. */
useUncached(const int & usage)96 static bool useUncached(const int& usage) {
97     if ((usage & GRALLOC_USAGE_PROTECTED) or
98         (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
99         ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
100         ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
101         return true;
102 
103     return false;
104 }
105 
106 //------------- MDPCapabilityInfo-----------------------//
MDPCapabilityInfo()107 MDPCapabilityInfo :: MDPCapabilityInfo() {
108   qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
109   qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported);
110 }
111 
112 //------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo()113 AdrenoMemInfo::AdrenoMemInfo()
114 {
115     LINK_adreno_compute_aligned_width_and_height = NULL;
116     LINK_adreno_compute_padding = NULL;
117     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
118     LINK_adreno_isUBWCSupportedByGpu = NULL;
119     LINK_adreno_get_gpu_pixel_alignment = NULL;
120 
121     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
122     if (libadreno_utils) {
123         *(void **)&LINK_adreno_compute_aligned_width_and_height =
124                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
125         *(void **)&LINK_adreno_compute_padding =
126                 ::dlsym(libadreno_utils, "compute_surface_padding");
127         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
128                 ::dlsym(libadreno_utils,
129                         "compute_compressedfmt_aligned_width_and_height");
130         *(void **)&LINK_adreno_isUBWCSupportedByGpu =
131                 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
132         *(void **)&LINK_adreno_get_gpu_pixel_alignment =
133                 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
134     }
135 
136     // Check if the overriding property debug.gralloc.gfx_ubwc_disable
137     // that disables UBWC allocations for the graphics stack is set
138     gfx_ubwc_disable = 0;
139     char property[PROPERTY_VALUE_MAX];
140     property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
141     if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
142        !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
143         gfx_ubwc_disable = 1;
144     }
145 }
146 
~AdrenoMemInfo()147 AdrenoMemInfo::~AdrenoMemInfo()
148 {
149     if (libadreno_utils) {
150         ::dlclose(libadreno_utils);
151     }
152 }
153 
getAlignedWidthAndHeight(const private_handle_t * hnd,int & aligned_w,int & aligned_h)154 void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
155                           int& aligned_h) {
156     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
157     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
158         int w = metadata->bufferDim.sliceWidth;
159         int h = metadata->bufferDim.sliceHeight;
160         int f = hnd->format;
161         int usage = 0;
162 
163         if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
164             usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
165         }
166 
167         getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
168     } else {
169         aligned_w = hnd->width;
170         aligned_h = hnd->height;
171     }
172 
173 }
174 
getUnalignedWidthAndHeight(const private_handle_t * hnd,int & unaligned_w,int & unaligned_h)175 void AdrenoMemInfo::getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w,
176                                                int& unaligned_h) {
177     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
178     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
179         unaligned_w = metadata->bufferDim.sliceWidth;
180         unaligned_h = metadata->bufferDim.sliceHeight;
181     } else {
182         unaligned_w = hnd->unaligned_width;
183         unaligned_h = hnd->unaligned_height;
184     }
185 }
186 
isUncompressedRgbFormat(int format)187 bool isUncompressedRgbFormat(int format)
188 {
189     bool is_rgb_format = false;
190 
191     switch (format)
192     {
193         case HAL_PIXEL_FORMAT_RGBA_8888:
194         case HAL_PIXEL_FORMAT_RGBX_8888:
195         case HAL_PIXEL_FORMAT_RGB_888:
196         case HAL_PIXEL_FORMAT_RGB_565:
197         case HAL_PIXEL_FORMAT_BGR_565:
198         case HAL_PIXEL_FORMAT_BGRA_8888:
199         case HAL_PIXEL_FORMAT_RGBA_5551:
200         case HAL_PIXEL_FORMAT_RGBA_4444:
201         case HAL_PIXEL_FORMAT_R_8:
202         case HAL_PIXEL_FORMAT_RG_88:
203         case HAL_PIXEL_FORMAT_BGRX_8888:
204         case HAL_PIXEL_FORMAT_BGR_888:
205         case HAL_PIXEL_FORMAT_RGBA_1010102:
206         case HAL_PIXEL_FORMAT_ARGB_2101010:
207         case HAL_PIXEL_FORMAT_RGBX_1010102:
208         case HAL_PIXEL_FORMAT_XRGB_2101010:
209         case HAL_PIXEL_FORMAT_BGRA_1010102:
210         case HAL_PIXEL_FORMAT_ABGR_2101010:
211         case HAL_PIXEL_FORMAT_BGRX_1010102:
212         case HAL_PIXEL_FORMAT_XBGR_2101010:    // Intentional fallthrough
213             is_rgb_format = true;
214             break;
215         default:
216             break;
217     }
218 
219     return is_rgb_format;
220 }
221 
getAlignedWidthAndHeight(int width,int height,int format,int usage,int & aligned_w,int & aligned_h)222 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
223                             int usage, int& aligned_w, int& aligned_h)
224 {
225     bool ubwc_enabled = isUBwcEnabled(format, usage);
226 
227     // Currently surface padding is only computed for RGB* surfaces.
228     if (isUncompressedRgbFormat(format) == true) {
229         int tileEnabled = ubwc_enabled;
230         getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
231     } else if (ubwc_enabled) {
232         getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
233     } else {
234         aligned_w = width;
235         aligned_h = height;
236         int alignment = 32;
237         switch (format)
238         {
239             case HAL_PIXEL_FORMAT_YCrCb_420_SP:
240             case HAL_PIXEL_FORMAT_YCbCr_420_SP:
241                 if (LINK_adreno_get_gpu_pixel_alignment) {
242                   alignment = LINK_adreno_get_gpu_pixel_alignment();
243                 }
244                 aligned_w = ALIGN(width, alignment);
245                 break;
246             case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
247                 aligned_w = ALIGN(width, alignment);
248                 break;
249             case HAL_PIXEL_FORMAT_RAW16:
250             case HAL_PIXEL_FORMAT_Y16:
251             case HAL_PIXEL_FORMAT_Y8:
252                 aligned_w = ALIGN(width, 16);
253                 break;
254             case HAL_PIXEL_FORMAT_RAW12:
255                 aligned_w = ALIGN(width * 12 / 8, 8);
256                 break;
257             case HAL_PIXEL_FORMAT_RAW10:
258                 aligned_w = ALIGN(width * 10 / 8, 8);
259                 break;
260             case HAL_PIXEL_FORMAT_RAW8:
261                 aligned_w = ALIGN(width, 8);
262                 break;
263             case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
264                 aligned_w = ALIGN(width, 128);
265                 break;
266             case HAL_PIXEL_FORMAT_YV12:
267             case HAL_PIXEL_FORMAT_YCbCr_422_SP:
268             case HAL_PIXEL_FORMAT_YCrCb_422_SP:
269             case HAL_PIXEL_FORMAT_YCbCr_422_I:
270             case HAL_PIXEL_FORMAT_YCrCb_422_I:
271             case HAL_PIXEL_FORMAT_YCbCr_420_P010:
272             case HAL_PIXEL_FORMAT_CbYCrY_422_I:
273                 aligned_w = ALIGN(width, 16);
274                 break;
275             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
276             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
277                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
278                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
279                 break;
280             case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
281                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
282                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
283                 break;
284             case HAL_PIXEL_FORMAT_BLOB:
285             case HAL_PIXEL_FORMAT_RAW_OPAQUE:
286                 break;
287             case HAL_PIXEL_FORMAT_NV21_ZSL:
288                 aligned_w = ALIGN(width, 64);
289                 aligned_h = ALIGN(height, 64);
290                 break;
291             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
292             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
293             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
294             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
295             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
296             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
297             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
298             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
299             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
300             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
301             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
302             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
303             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
304             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
305             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
306             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
307             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
308             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
309             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
310             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
311             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
312             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
313             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
314             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
315             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
316             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
317             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
318             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
319                 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
320                     int bytesPerPixel = 0;
321                     int raster_mode         = 0;   //Adreno unknown raster mode.
322                     int padding_threshold   = 512; //Threshold for padding
323                     //surfaces.
324 
325                     LINK_adreno_compute_compressedfmt_aligned_width_and_height(
326                         width, height, format, 0,raster_mode, padding_threshold,
327                         &aligned_w, &aligned_h, &bytesPerPixel);
328                 } else {
329                     ALOGW("%s: Warning!! Symbols" \
330                           " compute_compressedfmt_aligned_width_and_height" \
331                           " not found", __FUNCTION__);
332                 }
333                 break;
334             default: break;
335         }
336     }
337 }
338 
getGpuAlignedWidthHeight(int width,int height,int format,int tile_enabled,int & aligned_w,int & aligned_h)339 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
340                             int tile_enabled, int& aligned_w, int& aligned_h)
341 {
342     aligned_w = ALIGN(width, 32);
343     aligned_h = ALIGN(height, 32);
344 
345     // Don't add any additional padding if debug.gralloc.map_fb_memory
346     // is enabled
347     char property[PROPERTY_VALUE_MAX];
348     if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
349        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
350        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
351         return;
352     }
353 
354     int bpp = 4;
355     switch(format)
356     {
357         case HAL_PIXEL_FORMAT_RGB_888:
358             bpp = 3;
359             break;
360         case HAL_PIXEL_FORMAT_RGB_565:
361         case HAL_PIXEL_FORMAT_BGR_565:
362         case HAL_PIXEL_FORMAT_RGBA_5551:
363         case HAL_PIXEL_FORMAT_RGBA_4444:
364             bpp = 2;
365             break;
366         default: break;
367     }
368 
369     if (libadreno_utils) {
370         int raster_mode         = 0;   // Adreno unknown raster mode.
371         int padding_threshold   = 512; // Threshold for padding surfaces.
372         // the function below computes aligned width and aligned height
373         // based on linear or macro tile mode selected.
374         if(LINK_adreno_compute_aligned_width_and_height) {
375             LINK_adreno_compute_aligned_width_and_height(width,
376                                  height, bpp, tile_enabled,
377                                  raster_mode, padding_threshold,
378                                  &aligned_w, &aligned_h);
379 
380         } else if(LINK_adreno_compute_padding) {
381             int surface_tile_height = 1;   // Linear surface
382             aligned_w = LINK_adreno_compute_padding(width, bpp,
383                                  surface_tile_height, raster_mode,
384                                  padding_threshold);
385             ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
386                                                             __FUNCTION__);
387         } else {
388             ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
389                  "compute_aligned_width_and_height not found", __FUNCTION__);
390         }
391    }
392 }
393 
isUBWCSupportedByGPU(int format)394 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
395 {
396     if (!gfx_ubwc_disable && libadreno_utils) {
397         if (LINK_adreno_isUBWCSupportedByGpu) {
398             ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
399             return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
400         }
401     }
402     return 0;
403 }
404 
getGpuPixelFormat(int hal_format)405 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
406 {
407     switch (hal_format) {
408         case HAL_PIXEL_FORMAT_RGBA_8888:
409             return ADRENO_PIXELFORMAT_R8G8B8A8;
410         case HAL_PIXEL_FORMAT_RGBX_8888:
411             return ADRENO_PIXELFORMAT_R8G8B8X8;
412         case HAL_PIXEL_FORMAT_RGB_565:
413             return ADRENO_PIXELFORMAT_B5G6R5;
414         case HAL_PIXEL_FORMAT_BGR_565:
415             return ADRENO_PIXELFORMAT_R5G6B5;
416         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
417             return ADRENO_PIXELFORMAT_NV12;
418         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
419         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
420             return ADRENO_PIXELFORMAT_NV12_EXT;
421         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
422             return ADRENO_PIXELFORMAT_TP10;
423         case HAL_PIXEL_FORMAT_YCbCr_420_P010:
424         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
425             return ADRENO_PIXELFORMAT_P010;
426         case HAL_PIXEL_FORMAT_RGBA_1010102:
427             return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
428         case HAL_PIXEL_FORMAT_RGBX_1010102:
429             return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
430         case HAL_PIXEL_FORMAT_ABGR_2101010:
431             return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
432         default:
433             ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
434             break;
435     }
436     return ADRENO_PIXELFORMAT_UNKNOWN;
437 }
438 
439 //-------------- IAllocController-----------------------//
440 IAllocController* IAllocController::sController = NULL;
getInstance(void)441 IAllocController* IAllocController::getInstance(void)
442 {
443     if(sController == NULL) {
444         sController = new IonController();
445     }
446     return sController;
447 }
448 
449 
450 //-------------- IonController-----------------------//
IonController()451 IonController::IonController()
452 {
453     allocateIonMem();
454 
455     char property[PROPERTY_VALUE_MAX];
456     property_get("video.disable.ubwc", property, "0");
457     mDisableUBWCForEncode = atoi(property);
458 }
459 
allocateIonMem()460 void IonController::allocateIonMem()
461 {
462    mIonAlloc = new IonAlloc();
463 }
464 
allocate(alloc_data & data,int usage)465 int IonController::allocate(alloc_data& data, int usage)
466 {
467     int ionFlags = 0;
468     int ionHeapId = 0;
469     int ret;
470 
471     data.uncached = useUncached(usage);
472     data.allocType = 0;
473 
474     if(usage & GRALLOC_USAGE_PROTECTED) {
475         if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
476             ionHeapId = ION_HEAP(SD_HEAP_ID);
477             /*
478              * There is currently no flag in ION for Secure Display
479              * VM. Please add it to the define once available.
480              */
481             ionFlags |= ION_SD_FLAGS;
482         } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
483             ionHeapId = ION_HEAP(SD_HEAP_ID);
484             ionFlags |= (usage & GRALLOC_USAGE_HW_COMPOSER) ? ION_SC_PREVIEW_FLAGS : ION_SC_FLAGS;
485         } else {
486             ionHeapId = ION_HEAP(CP_HEAP_ID);
487             ionFlags |= ION_CP_FLAGS;
488         }
489     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
490         //MM Heap is exclusively a secure heap.
491         //If it is used for non secure cases, fallback to IOMMU heap
492         ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
493                                 cannot be used as an insecure heap!\
494                                 trying to use system heap instead !!");
495         ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
496     }
497 
498     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
499         ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
500 
501     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
502         ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
503 
504     if(ionFlags & ION_SECURE)
505          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
506 
507     // if no ion heap flags are set, default to system heap
508     if(!ionHeapId)
509         ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
510 
511     //At this point we should have the right heap set, there is no fallback
512     data.flags = ionFlags;
513     data.heapId = ionHeapId;
514     ret = mIonAlloc->alloc_buffer(data);
515 
516     if(ret >= 0 ) {
517         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
518     } else {
519         ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
520                 __FUNCTION__, ionHeapId, ionFlags);
521     }
522 
523     return ret;
524 }
525 
getAllocator(int flags)526 IMemAlloc* IonController::getAllocator(int flags)
527 {
528     IMemAlloc* memalloc = NULL;
529     if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
530         memalloc = mIonAlloc;
531     } else {
532         ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
533     }
534 
535     return memalloc;
536 }
537 
538 // helper function
getSize(int format,int width,int height,int usage,const int alignedw,const int alignedh)539 unsigned int getSize(int format, int width, int height, int usage,
540         const int alignedw, const int alignedh) {
541 
542     if (isUBwcEnabled(format, usage)) {
543         return getUBwcSize(width, height, format, alignedw, alignedh);
544     }
545 
546     unsigned int size = 0;
547     switch (format) {
548         case HAL_PIXEL_FORMAT_RGBA_8888:
549         case HAL_PIXEL_FORMAT_RGBX_8888:
550         case HAL_PIXEL_FORMAT_BGRA_8888:
551         case HAL_PIXEL_FORMAT_RGBA_1010102:
552         case HAL_PIXEL_FORMAT_ARGB_2101010:
553         case HAL_PIXEL_FORMAT_RGBX_1010102:
554         case HAL_PIXEL_FORMAT_XRGB_2101010:
555         case HAL_PIXEL_FORMAT_BGRA_1010102:
556         case HAL_PIXEL_FORMAT_ABGR_2101010:
557         case HAL_PIXEL_FORMAT_BGRX_1010102:
558         case HAL_PIXEL_FORMAT_XBGR_2101010:
559             size = alignedw * alignedh * 4;
560             break;
561         case HAL_PIXEL_FORMAT_RGB_888:
562             size = alignedw * alignedh * 3;
563             break;
564         case HAL_PIXEL_FORMAT_RGB_565:
565         case HAL_PIXEL_FORMAT_BGR_565:
566         case HAL_PIXEL_FORMAT_RGBA_5551:
567         case HAL_PIXEL_FORMAT_RGBA_4444:
568         case HAL_PIXEL_FORMAT_RAW16:
569         case HAL_PIXEL_FORMAT_Y16:
570             size = alignedw * alignedh * 2;
571             break;
572         case HAL_PIXEL_FORMAT_RAW12:
573             size = ALIGN(alignedw * alignedh, 4096);
574             break;
575         case HAL_PIXEL_FORMAT_RAW10:
576             size = ALIGN(alignedw * alignedh, 4096);
577             break;
578         case HAL_PIXEL_FORMAT_RAW8:
579         case HAL_PIXEL_FORMAT_Y8:
580             size = alignedw * alignedh;
581             break;
582             // adreno formats
583         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
584             size  = ALIGN(alignedw*alignedh, 4096);
585             size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
586             break;
587         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
588             // The chroma plane is subsampled,
589             // but the pitch in bytes is unchanged
590             // The GPU needs 4K alignment, but the video decoder needs 8K
591             size  = ALIGN( alignedw * alignedh, 8192);
592             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
593             break;
594         case HAL_PIXEL_FORMAT_YV12:
595             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
596                 ALOGE("w or h is odd for the YV12 format");
597                 return 0;
598             }
599             size = alignedw*alignedh +
600                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
601             size = ALIGN(size, (unsigned int)4096);
602             break;
603         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
604         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
605             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
606             break;
607         case HAL_PIXEL_FORMAT_YCbCr_420_P010:
608             size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, 4096);
609             break;
610         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
611         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
612         case HAL_PIXEL_FORMAT_YCbCr_422_I:
613         case HAL_PIXEL_FORMAT_YCrCb_422_I:
614         case HAL_PIXEL_FORMAT_CbYCrY_422_I:
615             if(width & 1) {
616                 ALOGE("width is odd for the YUV422_SP format");
617                 return 0;
618             }
619             size = ALIGN(alignedw * alignedh * 2, 4096);
620             break;
621         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
622         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
623             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
624             break;
625         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
626             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
627             break;
628         case HAL_PIXEL_FORMAT_BLOB:
629         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
630             if(height != 1) {
631                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
632                       must have height==1 ", __FUNCTION__);
633                 return 0;
634             }
635             size = width;
636             break;
637         case HAL_PIXEL_FORMAT_NV21_ZSL:
638             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
639             break;
640         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
641         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
642         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
643         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
644         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
645         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
646         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
647         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
648         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
649         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
650         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
651         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
652         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
653         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
654         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
655         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
656         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
657         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
658         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
659         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
660         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
661         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
662         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
663         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
664         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
665         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
666         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
667         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
668             size = alignedw * alignedh * ASTC_BLOCK_SIZE;
669             break;
670         default:
671             ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
672             return 0;
673     }
674     return size;
675 }
676 
getBufferSizeAndDimensions(int width,int height,int format,int & alignedw,int & alignedh)677 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
678         int& alignedw, int &alignedh)
679 {
680     unsigned int size;
681 
682     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
683             height,
684             format,
685             0,
686             alignedw,
687             alignedh);
688 
689     size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
690 
691     return size;
692 }
693 
694 
getBufferSizeAndDimensions(int width,int height,int format,int usage,int & alignedw,int & alignedh)695 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
696         int usage, int& alignedw, int &alignedh)
697 {
698     unsigned int size;
699 
700     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
701             height,
702             format,
703             usage,
704             alignedw,
705             alignedh);
706 
707     size = getSize(format, width, height, usage, alignedw, alignedh);
708 
709     return size;
710 }
711 
getYuvUbwcSPPlaneInfo(uint64_t base,int width,int height,int color_format,struct android_ycbcr * ycbcr)712 void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
713                            int color_format, struct android_ycbcr* ycbcr)
714 {
715     // UBWC buffer has these 4 planes in the following sequence:
716     // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
717     unsigned int y_meta_stride, y_meta_height, y_meta_size;
718     unsigned int y_stride, y_height, y_size;
719     unsigned int c_meta_stride, c_meta_height, c_meta_size;
720     unsigned int alignment = 4096;
721 
722     y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
723     y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
724     y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
725 
726     y_stride = VENUS_Y_STRIDE(color_format, width);
727     y_height = VENUS_Y_SCANLINES(color_format, height);
728     y_size = ALIGN((y_stride * y_height), alignment);
729 
730     c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
731     c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
732     c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
733 
734     ycbcr->y  = (void*)(base + y_meta_size);
735     ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
736     ycbcr->cr = (void*)(base + y_meta_size + y_size +
737                         c_meta_size + 1);
738     ycbcr->ystride = y_stride;
739     ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
740 }
741 
getYuvSPPlaneInfo(uint64_t base,int width,int height,int bpp,struct android_ycbcr * ycbcr)742 void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
743                        struct android_ycbcr* ycbcr)
744 {
745     unsigned int ystride, cstride;
746 
747     ystride = cstride = width * bpp;
748     ycbcr->y  = (void*)base;
749     ycbcr->cb = (void*)(base + ystride * height);
750     ycbcr->cr = (void*)(base + ystride * height + 1);
751     ycbcr->ystride = ystride;
752     ycbcr->cstride = cstride;
753     ycbcr->chroma_step = 2 * bpp;
754 }
755 
getYUVPlaneInfo(private_handle_t * hnd,struct android_ycbcr * ycbcr)756 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
757 {
758     int err = 0;
759     int width = hnd->width;
760     int height = hnd->height;
761     int format = hnd->format;
762 
763     unsigned int ystride, cstride;
764 
765     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
766     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
767 
768     // Check if UBWC buffer has been rendered in linear format.
769     if (metadata && (metadata->operation & LINEAR_FORMAT)) {
770         format = metadata->linearFormat;
771     }
772 
773     // Check metadata if the geometry has been updated.
774     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
775         int usage = 0;
776 
777         if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
778             usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
779         }
780 
781         AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
782                    metadata->bufferDim.sliceHeight, format, usage, width, height);
783     }
784 
785     // Get the chroma offsets from the handle width/height. We take advantage
786     // of the fact the width _is_ the stride
787     switch (format) {
788         //Semiplanar
789         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
790         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
791         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
792         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
793             getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
794         break;
795 
796         case HAL_PIXEL_FORMAT_YCbCr_420_P010:
797             getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
798         break;
799 
800         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
801             getYuvUbwcSPPlaneInfo(hnd->base, width, height,
802                                   COLOR_FMT_NV12_UBWC, ycbcr);
803             ycbcr->chroma_step = 2;
804         break;
805 
806         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
807             getYuvUbwcSPPlaneInfo(hnd->base, width, height,
808                                   COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
809             ycbcr->chroma_step = 3;
810         break;
811         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
812             getYuvUbwcSPPlaneInfo(hnd->base, width, height,
813                                   COLOR_FMT_P010_UBWC, ycbcr);
814             ycbcr->chroma_step = 4;
815         break;
816         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
817         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
818         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
819         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
820         case HAL_PIXEL_FORMAT_NV21_ZSL:
821         case HAL_PIXEL_FORMAT_RAW16:
822         case HAL_PIXEL_FORMAT_Y16:
823         case HAL_PIXEL_FORMAT_RAW12:
824         case HAL_PIXEL_FORMAT_RAW10:
825         case HAL_PIXEL_FORMAT_RAW8:
826         case HAL_PIXEL_FORMAT_Y8:
827             getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
828             std::swap(ycbcr->cb, ycbcr->cr);
829         break;
830 
831         //Planar
832         case HAL_PIXEL_FORMAT_YV12:
833             ystride = width;
834             cstride = ALIGN(width/2, 16);
835             ycbcr->y  = (void*)hnd->base;
836             ycbcr->cr = (void*)(hnd->base + ystride * height);
837             ycbcr->cb = (void*)(hnd->base + ystride * height +
838                     cstride * height/2);
839             ycbcr->ystride = ystride;
840             ycbcr->cstride = cstride;
841             ycbcr->chroma_step = 1;
842         break;
843         case HAL_PIXEL_FORMAT_CbYCrY_422_I:
844             ystride = width * 2;
845             cstride = 0;
846             ycbcr->y  = (void*)hnd->base;
847             ycbcr->cr = NULL;
848             ycbcr->cb = NULL;
849             ycbcr->ystride = ystride;
850             ycbcr->cstride = 0;
851             ycbcr->chroma_step = 0;
852         break;
853         //Unsupported formats
854         case HAL_PIXEL_FORMAT_YCbCr_422_I:
855         case HAL_PIXEL_FORMAT_YCrCb_422_I:
856         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
857         default:
858         ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
859         err = -EINVAL;
860     }
861     return err;
862 
863 }
864 
865 
866 
867 // Allocate buffer from width, height and format into a
868 // private_handle_t. It is the responsibility of the caller
869 // to free the buffer using the free_buffer function
alloc_buffer(private_handle_t ** pHnd,int w,int h,int format,int usage)870 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
871 {
872     alloc_data data;
873     int alignedw, alignedh;
874     gralloc::IAllocController* sAlloc =
875         gralloc::IAllocController::getInstance();
876     data.base = 0;
877     data.fd = -1;
878     data.offset = 0;
879     data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
880                                             alignedh);
881 
882     data.align = getpagesize();
883     data.uncached = useUncached(usage);
884     int allocFlags = usage;
885 
886     int err = sAlloc->allocate(data, allocFlags);
887     if (0 != err) {
888         ALOGE("%s: allocate failed", __FUNCTION__);
889         return -ENOMEM;
890     }
891 
892     if(isUBwcEnabled(format, usage)) {
893       data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
894     }
895 
896     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
897                                                  data.allocType, 0, format,
898                                                  alignedw, alignedh, -1, 0, 0, w, h);
899     hnd->base = (uint64_t) data.base;
900     hnd->offset = data.offset;
901     hnd->gpuaddr = 0;
902     *pHnd = hnd;
903     return 0;
904 }
905 
free_buffer(private_handle_t * hnd)906 void free_buffer(private_handle_t *hnd)
907 {
908     gralloc::IAllocController* sAlloc =
909         gralloc::IAllocController::getInstance();
910     if (hnd && hnd->fd > 0) {
911         IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
912         memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
913     }
914     if(hnd)
915         delete hnd;
916 
917 }
918 
919 // UBWC helper functions
isUBwcFormat(int format)920 static bool isUBwcFormat(int format)
921 {
922     // Explicitly defined UBWC formats
923     switch(format)
924     {
925         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
926         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
927         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
928             return true;
929         default:
930             return false;
931     }
932 }
933 
isUBwcSupported(int format)934 static bool isUBwcSupported(int format)
935 {
936     if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
937         // Existing HAL formats with UBWC support
938         switch(format)
939         {
940             case HAL_PIXEL_FORMAT_BGR_565:
941             case HAL_PIXEL_FORMAT_RGBA_8888:
942             case HAL_PIXEL_FORMAT_RGBX_8888:
943             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
944             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
945             case HAL_PIXEL_FORMAT_RGBA_1010102:
946             case HAL_PIXEL_FORMAT_RGBX_1010102:
947                 return true;
948             default:
949                 break;
950         }
951     }
952     return false;
953 }
954 
isUBwcEnabled(int format,int usage)955 bool isUBwcEnabled(int format, int usage)
956 {
957     // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
958     if (isUBwcFormat(format))
959         return true;
960 
961     if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
962         gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
963             return false;
964     }
965 
966     // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
967     // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
968     // usage flag and MDP supports the format.
969     if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
970         bool enable = true;
971         // Query GPU for UBWC only if buffer is intended to be used by GPU.
972         if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
973             enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
974         }
975         // Allow UBWC, only if CPU usage flags are not set
976         if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
977             GRALLOC_USAGE_SW_WRITE_MASK))) {
978             return true;
979         }
980     }
981     return false;
982 }
983 
getYuvUBwcWidthHeight(int width,int height,int format,int & aligned_w,int & aligned_h)984 static void getYuvUBwcWidthHeight(int width, int height, int format,
985         int& aligned_w, int& aligned_h)
986 {
987     switch (format)
988     {
989         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
990         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
991         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
992             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
993             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
994             break;
995         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
996             // The macro returns the stride which is 4/3 times the width, hence * 3/4
997             aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
998             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
999             break;
1000         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1001             // The macro returns the stride which is 2 times the width, hence / 2
1002             aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
1003             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
1004             break;
1005         default:
1006             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
1007             aligned_w = 0;
1008             aligned_h = 0;
1009             break;
1010     }
1011 }
1012 
getRgbUBwcBlockSize(int bpp,int & block_width,int & block_height)1013 static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
1014 {
1015     block_width = 0;
1016     block_height = 0;
1017 
1018     switch(bpp)
1019     {
1020          case 2:
1021          case 4:
1022              block_width = 16;
1023              block_height = 4;
1024              break;
1025          case 8:
1026              block_width = 8;
1027              block_height = 4;
1028              break;
1029          case 16:
1030              block_width = 4;
1031              block_height = 4;
1032              break;
1033          default:
1034              ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
1035              break;
1036     }
1037 }
1038 
getRgbUBwcMetaBufferSize(int width,int height,int bpp)1039 static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
1040 {
1041     unsigned int size = 0;
1042     int meta_width, meta_height;
1043     int block_width, block_height;
1044 
1045     getRgbUBwcBlockSize(bpp, block_width, block_height);
1046 
1047     if (!block_width || !block_height) {
1048         ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
1049         return size;
1050     }
1051 
1052     // Align meta buffer height to 16 blocks
1053     meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
1054 
1055     // Align meta buffer width to 64 blocks
1056     meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
1057 
1058     // Align meta buffer size to 4K
1059     size = ALIGN((meta_width * meta_height), 4096);
1060     return size;
1061 }
1062 
getUBwcSize(int width,int height,int format,const int alignedw,const int alignedh)1063 static unsigned int getUBwcSize(int width, int height, int format,
1064         const int alignedw, const int alignedh) {
1065 
1066     unsigned int size = 0;
1067     switch (format) {
1068         case HAL_PIXEL_FORMAT_BGR_565:
1069             size = alignedw * alignedh * 2;
1070             size += getRgbUBwcMetaBufferSize(width, height, 2);
1071             break;
1072         case HAL_PIXEL_FORMAT_RGBA_8888:
1073         case HAL_PIXEL_FORMAT_RGBX_8888:
1074         case HAL_PIXEL_FORMAT_RGBA_1010102:
1075         case HAL_PIXEL_FORMAT_RGBX_1010102:
1076             size = alignedw * alignedh * 4;
1077             size += getRgbUBwcMetaBufferSize(width, height, 4);
1078             break;
1079         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1080         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1081         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1082             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
1083             break;
1084         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1085             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
1086             break;
1087         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1088             size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
1089             break;
1090         default:
1091             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
1092             break;
1093     }
1094     return size;
1095 }
1096 
getRgbDataAddress(private_handle_t * hnd,void ** rgb_data)1097 int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
1098 {
1099     int err = 0;
1100 
1101     // This api is for RGB* formats
1102     if (!isUncompressedRgbFormat(hnd->format)) {
1103         return -EINVAL;
1104     }
1105 
1106     // linear buffer
1107     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
1108         *rgb_data = (void*)hnd->base;
1109         return err;
1110     }
1111 
1112     // Ubwc buffers
1113     unsigned int meta_size = 0;
1114     switch (hnd->format) {
1115         case HAL_PIXEL_FORMAT_BGR_565:
1116             meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
1117             break;
1118         case HAL_PIXEL_FORMAT_RGBA_8888:
1119         case HAL_PIXEL_FORMAT_RGBX_8888:
1120         case HAL_PIXEL_FORMAT_RGBA_1010102:
1121         case HAL_PIXEL_FORMAT_RGBX_1010102:
1122             meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
1123             break;
1124         default:
1125             ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
1126             err = -EINVAL;
1127             break;
1128     }
1129 
1130     *rgb_data = (void*)(hnd->base + meta_size);
1131     return err;
1132 }
1133 
getBufferLayout(private_handle_t * hnd,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)1134 int getBufferLayout(private_handle_t *hnd, uint32_t stride[4],
1135         uint32_t offset[4], uint32_t *num_planes) {
1136     if (!hnd || !stride || !offset || !num_planes) {
1137         return -EINVAL;
1138     }
1139 
1140     struct android_ycbcr yuvInfo = {};
1141     *num_planes = 1;
1142     stride[0] = 0;
1143 
1144     switch (hnd->format) {
1145         case HAL_PIXEL_FORMAT_RGB_565:
1146         case HAL_PIXEL_FORMAT_BGR_565:
1147         case HAL_PIXEL_FORMAT_RGBA_5551:
1148         case HAL_PIXEL_FORMAT_RGBA_4444:
1149             stride[0] = hnd->width * 2;
1150             break;
1151         case HAL_PIXEL_FORMAT_RGB_888:
1152             stride[0] = hnd->width * 3;
1153             break;
1154         case HAL_PIXEL_FORMAT_RGBA_8888:
1155         case HAL_PIXEL_FORMAT_BGRA_8888:
1156         case HAL_PIXEL_FORMAT_RGBX_8888:
1157         case HAL_PIXEL_FORMAT_BGRX_8888:
1158         case HAL_PIXEL_FORMAT_RGBA_1010102:
1159         case HAL_PIXEL_FORMAT_ARGB_2101010:
1160         case HAL_PIXEL_FORMAT_RGBX_1010102:
1161         case HAL_PIXEL_FORMAT_XRGB_2101010:
1162         case HAL_PIXEL_FORMAT_BGRA_1010102:
1163         case HAL_PIXEL_FORMAT_ABGR_2101010:
1164         case HAL_PIXEL_FORMAT_BGRX_1010102:
1165         case HAL_PIXEL_FORMAT_XBGR_2101010:
1166             stride[0] = hnd->width * 4;
1167             break;
1168     }
1169 
1170     // Format is RGB
1171     if (stride[0]) {
1172         return 0;
1173     }
1174 
1175     (*num_planes)++;
1176     int ret = getYUVPlaneInfo(hnd, &yuvInfo);
1177     if (ret < 0) {
1178         ALOGE("%s failed", __FUNCTION__);
1179         return ret;
1180     }
1181 
1182     stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
1183     offset[0] = static_cast<uint32_t>(
1184                     reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
1185     stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
1186     switch (hnd->format) {
1187         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1188         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1189         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1190         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1191         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1192         case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1193         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1194         case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1195             offset[1] = static_cast<uint32_t>(
1196                     reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1197             break;
1198         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1199         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1200         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1201             offset[1] = static_cast<uint32_t>(
1202                     reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1203             break;
1204         case HAL_PIXEL_FORMAT_YV12:
1205             offset[1] = static_cast<uint32_t>(
1206                     reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1207             stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
1208             offset[2] = static_cast<uint32_t>(
1209                     reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1210             (*num_planes)++;
1211             break;
1212         default:
1213             ALOGW("%s: Unsupported format %s", __FUNCTION__,
1214                     qdutils::GetHALPixelFormatString(hnd->format));
1215             ret = -EINVAL;
1216     }
1217 
1218     if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1219         std::fill(offset, offset + 4, 0);
1220     }
1221 
1222     return 0;
1223 }
1224