• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011-2014, 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 "gralloc_priv.h"
34 #include "alloc_controller.h"
35 #include "memalloc.h"
36 #include "ionalloc.h"
37 #include "gr.h"
38 #include "comptype.h"
39 #include "mdp_version.h"
40 
41 #ifdef VENUS_COLOR_FORMAT
42 #include <media/msm_media_info.h>
43 #else
44 #define VENUS_Y_STRIDE(args...) 0
45 #define VENUS_Y_SCANLINES(args...) 0
46 #define VENUS_BUFFER_SIZE(args...) 0
47 #endif
48 
49 #define ASTC_BLOCK_SIZE 16
50 
51 using namespace gralloc;
52 using namespace qdutils;
53 
54 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
55 
56 static void getUBwcWidthAndHeight(int, int, int, int&, int&);
57 static unsigned int getUBwcSize(int, int, int, const int, const int);
58 
59 //Common functions
canFallback(int usage,bool triedSystem)60 static bool canFallback(int usage, bool triedSystem)
61 {
62     // Fallback to system heap when alloc fails unless
63     // 1. Composition type is MDP
64     // 2. Alloc from system heap was already tried
65     // 3. The heap type is requsted explicitly
66     // 4. The heap type is protected
67     // 5. The buffer is meant for external display only
68 
69     if(QCCompositionType::getInstance().getCompositionType() &
70        COMPOSITION_TYPE_MDP)
71         return false;
72     if(triedSystem)
73         return false;
74     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
75         return false;
76     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
77         return false;
78     //Return true by default
79     return true;
80 }
81 
82 /* The default policy is to return cached buffers unless the client explicity
83  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
84  * read or written in software. Any combination with a _RARELY_ flag will be
85  * treated as uncached. */
useUncached(const int & usage)86 static bool useUncached(const int& usage) {
87     if ((usage & GRALLOC_USAGE_PROTECTED) or
88        (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
89        ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
90        ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
91         return true;
92 
93     return false;
94 }
95 
96 //-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo()97 AdrenoMemInfo::AdrenoMemInfo()
98 {
99     LINK_adreno_compute_aligned_width_and_height = NULL;
100     LINK_adreno_compute_padding = NULL;
101     LINK_adreno_isMacroTilingSupportedByGpu = NULL;
102     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
103     LINK_adreno_isUBWCSupportedByGpu = NULL;
104 
105     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
106     if (libadreno_utils) {
107         *(void **)&LINK_adreno_compute_aligned_width_and_height =
108                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
109         *(void **)&LINK_adreno_compute_padding =
110                 ::dlsym(libadreno_utils, "compute_surface_padding");
111         *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
112                 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
113         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
114                 ::dlsym(libadreno_utils,
115                         "compute_compressedfmt_aligned_width_and_height");
116         *(void **)&LINK_adreno_isUBWCSupportedByGpu =
117                 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
118     }
119 }
120 
~AdrenoMemInfo()121 AdrenoMemInfo::~AdrenoMemInfo()
122 {
123     if (libadreno_utils) {
124         ::dlclose(libadreno_utils);
125     }
126 }
127 
isMacroTilingSupportedByGPU()128 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
129 {
130     if ((libadreno_utils)) {
131         if(LINK_adreno_isMacroTilingSupportedByGpu) {
132             return LINK_adreno_isMacroTilingSupportedByGpu();
133         }
134     }
135     return 0;
136 }
137 
138 
isUncompressedRgbFormat(int format)139 bool isUncompressedRgbFormat(int format)
140 {
141     bool is_rgb_format = false;
142 
143     switch (format)
144     {
145         case HAL_PIXEL_FORMAT_RGBA_8888:
146         case HAL_PIXEL_FORMAT_RGBX_8888:
147         case HAL_PIXEL_FORMAT_RGB_888:
148         case HAL_PIXEL_FORMAT_RGB_565:
149         case HAL_PIXEL_FORMAT_BGRA_8888:
150         case HAL_PIXEL_FORMAT_RGBA_5551:
151         case HAL_PIXEL_FORMAT_RGBA_4444:
152         case HAL_PIXEL_FORMAT_R_8:
153         case HAL_PIXEL_FORMAT_RG_88:
154         case HAL_PIXEL_FORMAT_BGRX_8888:    // Intentional fallthrough
155             is_rgb_format = true;
156             break;
157         default:
158             break;
159     }
160 
161     return is_rgb_format;
162 }
163 
getAlignedWidthAndHeight(int width,int height,int format,int usage,int & aligned_w,int & aligned_h)164 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
165                             int usage, int& aligned_w, int& aligned_h)
166 {
167 
168     // Currently surface padding is only computed for RGB* surfaces.
169     if (isUncompressedRgbFormat(format) == true) {
170         int tileEnabled = isMacroTileEnabled(format, usage);
171         AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
172             height, format, tileEnabled, aligned_w, aligned_h);
173         return;
174     }
175 
176     if (isUBwcEnabled(format, usage)) {
177         getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
178         return;
179     }
180 
181     aligned_w = width;
182     aligned_h = height;
183     switch (format)
184     {
185         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
186         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
187             aligned_w = ALIGN(width, 32);
188             break;
189         case HAL_PIXEL_FORMAT_RAW16:
190             aligned_w = ALIGN(width, 16);
191             break;
192         case HAL_PIXEL_FORMAT_RAW10:
193             aligned_w = ALIGN(width * 10 /8, 8);
194             break;
195         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
196             aligned_w = ALIGN(width, 128);
197             break;
198         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
199         case HAL_PIXEL_FORMAT_YV12:
200         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
201         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
202         case HAL_PIXEL_FORMAT_YCbCr_422_I:
203         case HAL_PIXEL_FORMAT_YCrCb_422_I:
204             aligned_w = ALIGN(width, 16);
205             break;
206         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
207         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
208             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
209             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
210             break;
211         case HAL_PIXEL_FORMAT_BLOB:
212         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
213             break;
214         case HAL_PIXEL_FORMAT_NV21_ZSL:
215             aligned_w = ALIGN(width, 64);
216             aligned_h = ALIGN(height, 64);
217             break;
218         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
219         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
220         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
221         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
222         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
223         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
224         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
225         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
226         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
227         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
228         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
229         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
230         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
231         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
232         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
233         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
234         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
235         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
236         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
237         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
238         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
239         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
240         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
241         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
242         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
243         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
244         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
245         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
246             if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
247                 int bytesPerPixel = 0;
248                 int raster_mode         = 0;   //Adreno unknown raster mode.
249                 int padding_threshold   = 512; //Threshold for padding
250                 //surfaces.
251 
252                 LINK_adreno_compute_compressedfmt_aligned_width_and_height(
253                     width, height, format, 0,raster_mode, padding_threshold,
254                     &aligned_w, &aligned_h, &bytesPerPixel);
255             } else {
256                 ALOGW("%s: Warning!! Symbols" \
257                       " compute_compressedfmt_aligned_width_and_height" \
258                       " not found", __FUNCTION__);
259             }
260             break;
261         default: break;
262     }
263 }
264 
getGpuAlignedWidthHeight(int width,int height,int format,int tile_enabled,int & aligned_w,int & aligned_h)265 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
266                             int tile_enabled, int& aligned_w, int& aligned_h)
267 {
268     aligned_w = ALIGN(width, 32);
269     aligned_h = ALIGN(height, 32);
270 
271     // Don't add any additional padding if debug.gralloc.map_fb_memory
272     // is enabled
273     char property[PROPERTY_VALUE_MAX];
274     if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
275        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
276        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
277         return;
278     }
279 
280     int bpp = 4;
281     switch(format)
282     {
283         case HAL_PIXEL_FORMAT_RGB_888:
284             bpp = 3;
285             break;
286         case HAL_PIXEL_FORMAT_RGB_565:
287         case HAL_PIXEL_FORMAT_RGBA_5551:
288         case HAL_PIXEL_FORMAT_RGBA_4444:
289             bpp = 2;
290             break;
291         default: break;
292     }
293 
294     if (libadreno_utils) {
295         int raster_mode         = 0;   // Adreno unknown raster mode.
296         int padding_threshold   = 512; // Threshold for padding surfaces.
297         // the function below computes aligned width and aligned height
298         // based on linear or macro tile mode selected.
299         if(LINK_adreno_compute_aligned_width_and_height) {
300             LINK_adreno_compute_aligned_width_and_height(width,
301                                  height, bpp, tile_enabled,
302                                  raster_mode, padding_threshold,
303                                  &aligned_w, &aligned_h);
304 
305         } else if(LINK_adreno_compute_padding) {
306             int surface_tile_height = 1;   // Linear surface
307             aligned_w = LINK_adreno_compute_padding(width, bpp,
308                                  surface_tile_height, raster_mode,
309                                  padding_threshold);
310             ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
311                                                             __FUNCTION__);
312         } else {
313             ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
314                  "compute_aligned_width_and_height not found", __FUNCTION__);
315         }
316    }
317 }
318 
isUBWCSupportedByGPU(int format)319 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
320 {
321     if (libadreno_utils) {
322         if (LINK_adreno_isUBWCSupportedByGpu) {
323             ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
324             return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
325         }
326     }
327     return 0;
328 }
329 
getGpuPixelFormat(int hal_format)330 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
331 {
332     switch (hal_format) {
333         case HAL_PIXEL_FORMAT_RGBA_8888:
334             return ADRENO_PIXELFORMAT_R8G8B8A8;
335         case HAL_PIXEL_FORMAT_RGB_565:
336             return ADRENO_PIXELFORMAT_B5G6R5;
337         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
338         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
339         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
340             return ADRENO_PIXELFORMAT_NV12;
341         default:
342             ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
343             break;
344     }
345     return ADRENO_PIXELFORMAT_UNKNOWN;
346 }
347 
348 //-------------- IAllocController-----------------------//
349 IAllocController* IAllocController::sController = NULL;
getInstance(void)350 IAllocController* IAllocController::getInstance(void)
351 {
352     if(sController == NULL) {
353         sController = new IonController();
354     }
355     return sController;
356 }
357 
358 
359 //-------------- IonController-----------------------//
IonController()360 IonController::IonController()
361 {
362     allocateIonMem();
363 }
364 
allocateIonMem()365 void IonController::allocateIonMem()
366 {
367    mIonAlloc = new IonAlloc();
368 }
369 
allocate(alloc_data & data,int usage)370 int IonController::allocate(alloc_data& data, int usage)
371 {
372     int ionFlags = 0;
373     int ret;
374 
375     data.uncached = useUncached(usage);
376     data.allocType = 0;
377 
378     if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
379         ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
380 
381     if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
382         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
383 
384     if(usage & GRALLOC_USAGE_PROTECTED) {
385         ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
386         ionFlags |= ION_SECURE;
387 #ifdef ION_FLAG_ALLOW_NON_CONTIG
388         if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
389             ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
390         }
391 #endif
392     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
393         //MM Heap is exclusively a secure heap.
394         //If it is used for non secure cases, fallback to IOMMU heap
395         ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
396                                 cannot be used as an insecure heap!\
397                                 trying to use IOMMU instead !!");
398         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
399     }
400 
401     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
402         ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
403 
404     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
405         ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
406 
407     if(ionFlags & ION_SECURE)
408          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
409 
410     // if no flags are set, default to
411     // SF + IOMMU heaps, so that bypass can work
412     // we can fall back to system heap if
413     // we run out.
414     if(!ionFlags)
415         ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
416 
417     data.flags = ionFlags;
418     ret = mIonAlloc->alloc_buffer(data);
419 
420     // Fallback
421     if(ret < 0 && canFallback(usage,
422                               (ionFlags & ION_SYSTEM_HEAP_ID)))
423     {
424         ALOGW("Falling back to system heap");
425         data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
426         ret = mIonAlloc->alloc_buffer(data);
427     }
428 
429     if(ret >= 0 ) {
430         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
431     }
432 
433     return ret;
434 }
435 
getAllocator(int flags)436 IMemAlloc* IonController::getAllocator(int flags)
437 {
438     IMemAlloc* memalloc = NULL;
439     if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
440         memalloc = mIonAlloc;
441     } else {
442         ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
443     }
444 
445     return memalloc;
446 }
447 
isMacroTileEnabled(int format,int usage)448 bool isMacroTileEnabled(int format, int usage)
449 {
450     bool tileEnabled = false;
451 
452     // Check whether GPU & MDSS supports MacroTiling feature
453     if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
454             qdutils::MDPVersion::getInstance().supportsMacroTile())
455     {
456         // check the format
457         switch(format)
458         {
459             case  HAL_PIXEL_FORMAT_RGBA_8888:
460             case  HAL_PIXEL_FORMAT_RGBX_8888:
461             case  HAL_PIXEL_FORMAT_BGRA_8888:
462             case  HAL_PIXEL_FORMAT_RGB_565:
463                 {
464                     tileEnabled = true;
465                     // check the usage flags
466                     if (usage & (GRALLOC_USAGE_SW_READ_MASK |
467                                 GRALLOC_USAGE_SW_WRITE_MASK)) {
468                         // Application intends to use CPU for rendering
469                         tileEnabled = false;
470                     }
471                     break;
472                 }
473             default:
474                 break;
475         }
476     }
477     return tileEnabled;
478 }
479 
480 // helper function
getSize(int format,int width,int height,int usage,const int alignedw,const int alignedh)481 unsigned int getSize(int format, int width, int height, int usage,
482         const int alignedw, const int alignedh) {
483 
484     if (isUBwcEnabled(format, usage)) {
485         return getUBwcSize(width, height, format, alignedw, alignedh);
486     }
487 
488     unsigned int size = 0;
489     switch (format) {
490         case HAL_PIXEL_FORMAT_RGBA_8888:
491         case HAL_PIXEL_FORMAT_RGBX_8888:
492         case HAL_PIXEL_FORMAT_BGRA_8888:
493             size = alignedw * alignedh * 4;
494             break;
495         case HAL_PIXEL_FORMAT_RGB_888:
496             size = alignedw * alignedh * 3;
497             break;
498         case HAL_PIXEL_FORMAT_RGB_565:
499         case HAL_PIXEL_FORMAT_RGBA_5551:
500         case HAL_PIXEL_FORMAT_RGBA_4444:
501         case HAL_PIXEL_FORMAT_RAW16:
502             size = alignedw * alignedh * 2;
503             break;
504         case HAL_PIXEL_FORMAT_RAW10:
505             size = ALIGN(alignedw * alignedh, 4096);
506             break;
507             // adreno formats
508         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
509             size  = ALIGN(alignedw*alignedh, 4096);
510             size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
511             break;
512         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
513             // The chroma plane is subsampled,
514             // but the pitch in bytes is unchanged
515             // The GPU needs 4K alignment, but the video decoder needs 8K
516             size  = ALIGN( alignedw * alignedh, 8192);
517             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
518             break;
519         case HAL_PIXEL_FORMAT_YV12:
520             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
521                 ALOGE("w or h is odd for the YV12 format");
522                 return 0;
523             }
524             size = alignedw*alignedh +
525                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
526             size = ALIGN(size, (unsigned int)4096);
527             break;
528         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
529         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
530             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
531             break;
532         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
533         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
534         case HAL_PIXEL_FORMAT_YCbCr_422_I:
535         case HAL_PIXEL_FORMAT_YCrCb_422_I:
536             if(width & 1) {
537                 ALOGE("width is odd for the YUV422_SP format");
538                 return 0;
539             }
540             size = ALIGN(alignedw * alignedh * 2, 4096);
541             break;
542         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
543         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
544             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
545             break;
546         case HAL_PIXEL_FORMAT_BLOB:
547         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
548             if(height != 1) {
549                 ALOGE("%s: Buffers with RAW_OPAQUE/blob formats \
550                       must have height==1 ", __FUNCTION__);
551                 return 0;
552             }
553             size = width;
554             break;
555         case HAL_PIXEL_FORMAT_NV21_ZSL:
556             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
557             break;
558         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
559         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
560         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
561         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
562         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
563         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
564         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
565         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
566         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
567         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
568         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
569         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
570         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
571         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
572         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
573         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
574         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
575         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
576         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
577         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
578         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
579         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
580         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
581         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
582         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
583         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
584         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
585         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
586             size = alignedw * alignedh * ASTC_BLOCK_SIZE;
587             break;
588         default:
589             ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
590             return 0;
591     }
592     return size;
593 }
594 
getBufferSizeAndDimensions(int width,int height,int format,int & alignedw,int & alignedh)595 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
596         int& alignedw, int &alignedh)
597 {
598     unsigned int size;
599 
600     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
601             height,
602             format,
603             0,
604             alignedw,
605             alignedh);
606 
607     size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
608 
609     return size;
610 }
611 
612 
getBufferSizeAndDimensions(int width,int height,int format,int usage,int & alignedw,int & alignedh)613 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
614         int usage, int& alignedw, int &alignedh)
615 {
616     unsigned int size;
617 
618     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
619             height,
620             format,
621             usage,
622             alignedw,
623             alignedh);
624 
625     size = getSize(format, width, height, usage, alignedw, alignedh);
626 
627     return size;
628 }
629 
630 
getBufferAttributes(int width,int height,int format,int usage,int & alignedw,int & alignedh,int & tileEnabled,unsigned int & size)631 void getBufferAttributes(int width, int height, int format, int usage,
632         int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
633 {
634     tileEnabled = isMacroTileEnabled(format, usage);
635 
636     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
637             height,
638             format,
639             usage,
640             alignedw,
641             alignedh);
642     size = getSize(format, width, height, usage, alignedw, alignedh);
643 }
644 
getYUVPlaneInfo(private_handle_t * hnd,struct android_ycbcr * ycbcr)645 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
646 {
647     int err = 0;
648     unsigned int ystride, cstride;
649     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
650 
651     // Get the chroma offsets from the handle width/height. We take advantage
652     // of the fact the width _is_ the stride
653     switch (hnd->format) {
654         //Semiplanar
655         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
656         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
657         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
658         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
659             ystride = cstride = hnd->width;
660             ycbcr->y  = (void*)hnd->base;
661             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
662             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
663             ycbcr->ystride = ystride;
664             ycbcr->cstride = cstride;
665             ycbcr->chroma_step = 2;
666         break;
667 
668         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
669         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
670         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
671         case HAL_PIXEL_FORMAT_NV21_ZSL:
672         case HAL_PIXEL_FORMAT_RAW10:
673         case HAL_PIXEL_FORMAT_RAW16:
674             ystride = cstride = hnd->width;
675             ycbcr->y  = (void*)hnd->base;
676             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
677             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
678             ycbcr->ystride = ystride;
679             ycbcr->cstride = cstride;
680             ycbcr->chroma_step = 2;
681         break;
682 
683         //Planar
684         case HAL_PIXEL_FORMAT_YV12:
685             ystride = hnd->width;
686             cstride = ALIGN(hnd->width/2, 16);
687             ycbcr->y  = (void*)hnd->base;
688             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
689             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
690                     cstride * hnd->height/2);
691             ycbcr->ystride = ystride;
692             ycbcr->cstride = cstride;
693             ycbcr->chroma_step = 1;
694 
695         break;
696         //Unsupported formats
697         case HAL_PIXEL_FORMAT_YCbCr_422_I:
698         case HAL_PIXEL_FORMAT_YCrCb_422_I:
699         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
700         default:
701         ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
702                 hnd->format);
703         err = -EINVAL;
704     }
705     return err;
706 
707 }
708 
709 
710 
711 // Allocate buffer from width, height and format into a
712 // private_handle_t. It is the responsibility of the caller
713 // to free the buffer using the free_buffer function
alloc_buffer(private_handle_t ** pHnd,int w,int h,int format,int usage)714 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
715 {
716     alloc_data data;
717     int alignedw, alignedh;
718     gralloc::IAllocController* sAlloc =
719         gralloc::IAllocController::getInstance();
720     data.base = 0;
721     data.fd = -1;
722     data.offset = 0;
723     data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
724                                             alignedh);
725 
726     data.align = getpagesize();
727     data.uncached = useUncached(usage);
728     int allocFlags = usage;
729 
730     int err = sAlloc->allocate(data, allocFlags);
731     if (0 != err) {
732         ALOGE("%s: allocate failed", __FUNCTION__);
733         return -ENOMEM;
734     }
735 
736     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
737                                                  data.allocType, 0, format,
738                                                  alignedw, alignedh);
739     hnd->base = (uint64_t) data.base;
740     hnd->offset = data.offset;
741     hnd->gpuaddr = 0;
742     *pHnd = hnd;
743     return 0;
744 }
745 
free_buffer(private_handle_t * hnd)746 void free_buffer(private_handle_t *hnd)
747 {
748     gralloc::IAllocController* sAlloc =
749         gralloc::IAllocController::getInstance();
750     if (hnd && hnd->fd > 0) {
751         IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
752         memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
753     }
754     if(hnd)
755         delete hnd;
756 
757 }
758 
759 // UBWC helper functions
isUBwcFormat(int format)760 static bool isUBwcFormat(int format)
761 {
762     // Explicitly defined UBWC formats
763     switch(format)
764     {
765         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
766             return true;
767         default:
768             return false;
769     }
770 }
771 
isUBwcSupported(int format)772 static bool isUBwcSupported(int format)
773 {
774     // Existing HAL formats with UBWC support
775     switch(format)
776     {
777         case HAL_PIXEL_FORMAT_RGB_565:
778         case HAL_PIXEL_FORMAT_RGBA_8888:
779         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
780         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
781             return true;
782         default:
783             return false;
784     }
785 }
786 
isUBwcEnabled(int format,int usage)787 bool isUBwcEnabled(int format, int usage)
788 {
789     if (isUBwcFormat(format) ||
790         ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)))
791     {
792         // Allow UBWC, only if GPU supports it and CPU usage flags are not set
793         if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
794             !(usage & (GRALLOC_USAGE_SW_READ_MASK |
795                       GRALLOC_USAGE_SW_WRITE_MASK))) {
796             return true;
797         }
798     }
799     return false;
800 }
801 
getUBwcWidthAndHeight(int width,int height,int format,int & aligned_w,int & aligned_h)802 static void getUBwcWidthAndHeight(int width, int height, int format,
803         int& aligned_w, int& aligned_h)
804 {
805     switch (format)
806     {
807         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
808         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
809         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
810             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
811             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
812             break;
813         default:
814             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
815             aligned_w = 0;
816             aligned_h = 0;
817             break;
818     }
819 }
820 
getUBwcBlockSize(int bpp,int & block_width,int & block_height)821 static void getUBwcBlockSize(int bpp, int& block_width, int& block_height)
822 {
823     block_width = 0;
824     block_height = 0;
825 
826     switch(bpp)
827     {
828          case 2:
829          case 4:
830              block_width = 16;
831              block_height = 4;
832              break;
833          case 8:
834              block_width = 8;
835              block_height = 4;
836              break;
837          case 16:
838              block_width = 4;
839              block_height = 4;
840              break;
841          default:
842              ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
843              break;
844     }
845 }
846 
getUBwcMetaBufferSize(int width,int height,int bpp)847 static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp)
848 {
849     unsigned int size = 0;
850     int meta_width, meta_height;
851     int block_width, block_height;
852 
853     getUBwcBlockSize(bpp, block_width, block_height);
854 
855     if (!block_width || !block_height) {
856         ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
857         return size;
858     }
859 
860     // Align meta buffer height to 16 blocks
861     meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
862 
863     // Align meta buffer width to 64 blocks
864     meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
865 
866     // Align meta buffer size to 4K
867     size = ((meta_width * meta_height), 4096);
868     return size;
869 }
870 
getUBwcSize(int width,int height,int format,const int alignedw,const int alignedh)871 static unsigned int getUBwcSize(int width, int height, int format,
872         const int alignedw, const int alignedh) {
873 
874     unsigned int size = 0;
875     switch (format) {
876         case HAL_PIXEL_FORMAT_RGB_565:
877             size = alignedw * alignedh * 2;
878             size += getUBwcMetaBufferSize(width, height, 2);
879             break;
880         case HAL_PIXEL_FORMAT_RGBA_8888:
881             size = alignedw * alignedh * 4;
882             size += getUBwcMetaBufferSize(width, height, 4);
883             break;
884         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
885         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
886         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
887             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
888             break;
889         default:
890             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
891             break;
892     }
893     return size;
894 }
895