• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (c) 2011-2014,2016, 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  //Common functions
canFallback(int usage,bool triedSystem)57  static bool canFallback(int usage, bool triedSystem)
58  {
59      // Fallback to system heap when alloc fails unless
60      // 1. Composition type is MDP
61      // 2. Alloc from system heap was already tried
62      // 3. The heap type is requsted explicitly
63      // 4. The heap type is protected
64      // 5. The buffer is meant for external display only
65  
66      if(QCCompositionType::getInstance().getCompositionType() &
67         COMPOSITION_TYPE_MDP)
68          return false;
69      if(triedSystem)
70          return false;
71      if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
72          return false;
73      if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
74          return false;
75      //Return true by default
76      return true;
77  }
78  
79  /* The default policy is to return cached buffers unless the client explicity
80   * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
81   * read or written in software. Any combination with a _RARELY_ flag will be
82   * treated as uncached. */
useUncached(const int & usage)83  static bool useUncached(const int& usage) {
84      if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
85              ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
86              GRALLOC_USAGE_SW_WRITE_RARELY) or
87              ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
88              GRALLOC_USAGE_SW_READ_RARELY))
89          return true;
90  
91      return false;
92  }
93  
94  //-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo()95  AdrenoMemInfo::AdrenoMemInfo()
96  {
97      LINK_adreno_compute_aligned_width_and_height = NULL;
98      LINK_adreno_compute_padding = NULL;
99      LINK_adreno_isMacroTilingSupportedByGpu = NULL;
100      LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
101      LINK_adreno_get_gpu_pixel_alignment = NULL;
102  
103      libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
104      if (libadreno_utils) {
105          *(void **)&LINK_adreno_compute_aligned_width_and_height =
106                  ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
107          *(void **)&LINK_adreno_compute_padding =
108                  ::dlsym(libadreno_utils, "compute_surface_padding");
109          *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
110                  ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
111          *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
112                  ::dlsym(libadreno_utils,
113                          "compute_compressedfmt_aligned_width_and_height");
114          *(void **)&LINK_adreno_get_gpu_pixel_alignment =
115                  ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
116      }
117  }
118  
~AdrenoMemInfo()119  AdrenoMemInfo::~AdrenoMemInfo()
120  {
121      if (libadreno_utils) {
122          ::dlclose(libadreno_utils);
123      }
124  }
125  
isMacroTilingSupportedByGPU()126  int AdrenoMemInfo::isMacroTilingSupportedByGPU()
127  {
128      if ((libadreno_utils)) {
129          if(LINK_adreno_isMacroTilingSupportedByGpu) {
130              return LINK_adreno_isMacroTilingSupportedByGpu();
131          }
132      }
133      return 0;
134  }
135  
136  
getAlignedWidthAndHeight(int width,int height,int format,int tile_enabled,int & aligned_w,int & aligned_h)137  void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
138                              int tile_enabled, int& aligned_w, int& aligned_h)
139  {
140      aligned_w = width;
141      aligned_h = height;
142      // Currently surface padding is only computed for RGB* surfaces.
143      if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
144          aligned_w = ALIGN(width, 32);
145          aligned_h = ALIGN(height, 32);
146          // Don't add any additional padding if debug.gralloc.map_fb_memory
147          // is enabled
148          char property[PROPERTY_VALUE_MAX];
149          if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
150             (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
151             (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
152                return;
153          }
154  
155          int bpp = 4;
156          switch(format)
157          {
158              case HAL_PIXEL_FORMAT_RGB_888:
159                  bpp = 3;
160                  break;
161              case HAL_PIXEL_FORMAT_RGB_565:
162                  bpp = 2;
163                  break;
164              default: break;
165          }
166          if (libadreno_utils) {
167              int raster_mode         = 0;   // Adreno unknown raster mode.
168              int padding_threshold   = 512; // Threshold for padding surfaces.
169              // the function below computes aligned width and aligned height
170              // based on linear or macro tile mode selected.
171              if(LINK_adreno_compute_aligned_width_and_height) {
172                  LINK_adreno_compute_aligned_width_and_height(width,
173                                       height, bpp, tile_enabled,
174                                       raster_mode, padding_threshold,
175                                       &aligned_w, &aligned_h);
176  
177              } else if(LINK_adreno_compute_padding) {
178                  int surface_tile_height = 1;   // Linear surface
179                  aligned_w = LINK_adreno_compute_padding(width, bpp,
180                                       surface_tile_height, raster_mode,
181                                       padding_threshold);
182                  ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
183                                                              __FUNCTION__);
184              } else {
185                  ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
186                      "compute_aligned_width_and_height not found", __FUNCTION__);
187              }
188          }
189      } else {
190          int alignment = 32;
191          switch (format)
192          {
193              case HAL_PIXEL_FORMAT_YCrCb_420_SP:
194              case HAL_PIXEL_FORMAT_YCbCr_420_SP:
195                  if (LINK_adreno_get_gpu_pixel_alignment) {
196                      alignment = LINK_adreno_get_gpu_pixel_alignment();
197                  }
198                  aligned_w = ALIGN(width, alignment);
199                  break;
200              case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
201                  aligned_w = ALIGN(width, alignment);
202                  break;
203              case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
204                  aligned_w = ALIGN(width, 128);
205                  break;
206              case HAL_PIXEL_FORMAT_YV12:
207              case HAL_PIXEL_FORMAT_YCbCr_422_SP:
208              case HAL_PIXEL_FORMAT_YCrCb_422_SP:
209              case HAL_PIXEL_FORMAT_YCbCr_422_I:
210              case HAL_PIXEL_FORMAT_YCrCb_422_I:
211                  aligned_w = ALIGN(width, 16);
212                  break;
213              case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
214              case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
215                  aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
216                  aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
217                  break;
218              case HAL_PIXEL_FORMAT_BLOB:
219                  break;
220              case HAL_PIXEL_FORMAT_NV21_ZSL:
221                  aligned_w = ALIGN(width, 64);
222                  aligned_h = ALIGN(height, 64);
223                  break;
224              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
225              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
226              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
227              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
228              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
229              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
230              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
231              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
232              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
233              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
234              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
235              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
236              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
237              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
238              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
239              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
240              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
241              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
242              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
243              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
244              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
245              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
246              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
247              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
248              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
249              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
250              case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
251              case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
252                  if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
253                      int bytesPerPixel = 0;
254                      int raster_mode         = 0;   //Adreno unknown raster mode.
255                      int padding_threshold   = 512; //Threshold for padding
256                      //surfaces.
257  
258                      LINK_adreno_compute_compressedfmt_aligned_width_and_height(
259                          width, height, format, 0,raster_mode, padding_threshold,
260                          &aligned_w, &aligned_h, &bytesPerPixel);
261  
262                  } else {
263                      ALOGW("%s: Warning!! Symbols" \
264                            " compute_compressedfmt_aligned_width_and_height" \
265                            " not found", __FUNCTION__);
266                  }
267                  break;
268              default: break;
269          }
270      }
271  }
272  
273  //-------------- IAllocController-----------------------//
274  IAllocController* IAllocController::sController = NULL;
getInstance(void)275  IAllocController* IAllocController::getInstance(void)
276  {
277      if(sController == NULL) {
278          sController = new IonController();
279      }
280      return sController;
281  }
282  
283  
284  //-------------- IonController-----------------------//
IonController()285  IonController::IonController()
286  {
287      allocateIonMem();
288  }
289  
allocateIonMem()290  void IonController::allocateIonMem()
291  {
292     mIonAlloc = new IonAlloc();
293  }
294  
allocate(alloc_data & data,int usage)295  int IonController::allocate(alloc_data& data, int usage)
296  {
297      int ionFlags = 0;
298      int ret;
299  
300      data.uncached = useUncached(usage);
301      data.allocType = 0;
302  
303      if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
304          ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
305  
306      if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
307          ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
308  
309      if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
310          ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
311  
312      if(usage & GRALLOC_USAGE_PROTECTED) {
313          if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
314              ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
315              ionFlags |= ION_SECURE;
316          } else {
317              // for targets/OEMs which do not need HW level protection
318              // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
319              ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
320          }
321      } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
322          //MM Heap is exclusively a secure heap.
323          //If it is used for non secure cases, fallback to IOMMU heap
324          ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
325                                  cannot be used as an insecure heap!\
326                                  trying to use IOMMU instead !!");
327          ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
328      }
329  
330      if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
331          ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
332  
333      if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
334          ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
335  
336      if(ionFlags & ION_SECURE)
337           data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
338  
339      // if no flags are set, default to
340      // SF + IOMMU heaps, so that bypass can work
341      // we can fall back to system heap if
342      // we run out.
343      if(!ionFlags)
344          ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
345  
346      data.flags = ionFlags;
347      ret = mIonAlloc->alloc_buffer(data);
348  
349      // Fallback
350      if(ret < 0 && canFallback(usage,
351                                (ionFlags & ION_SYSTEM_HEAP_ID)))
352      {
353          ALOGW("Falling back to system heap");
354          data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
355          ret = mIonAlloc->alloc_buffer(data);
356      }
357  
358      if(ret >= 0 ) {
359          data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
360      }
361  
362      return ret;
363  }
364  
getAllocator(int flags)365  IMemAlloc* IonController::getAllocator(int flags)
366  {
367      IMemAlloc* memalloc = NULL;
368      if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
369          memalloc = mIonAlloc;
370      } else {
371          ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
372      }
373  
374      return memalloc;
375  }
376  
isMacroTileEnabled(int format,int usage)377  bool isMacroTileEnabled(int format, int usage)
378  {
379      bool tileEnabled = false;
380  
381      // Check whether GPU & MDSS supports MacroTiling feature
382      if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
383              qdutils::MDPVersion::getInstance().supportsMacroTile())
384      {
385          // check the format
386          switch(format)
387          {
388              case  HAL_PIXEL_FORMAT_RGBA_8888:
389              case  HAL_PIXEL_FORMAT_RGBX_8888:
390              case  HAL_PIXEL_FORMAT_BGRA_8888:
391              case  HAL_PIXEL_FORMAT_RGB_565:
392                  {
393                      tileEnabled = true;
394                      // check the usage flags
395                      if (usage & (GRALLOC_USAGE_SW_READ_MASK |
396                                  GRALLOC_USAGE_SW_WRITE_MASK)) {
397                          // Application intends to use CPU for rendering
398                          tileEnabled = false;
399                      }
400                      break;
401                  }
402              default:
403                  break;
404          }
405      }
406      return tileEnabled;
407  }
408  
409  // helper function
getSize(int format,int width,int height,const int alignedw,const int alignedh)410  unsigned int getSize(int format, int width, int height, const int alignedw,
411          const int alignedh) {
412      unsigned int size = 0;
413  
414      switch (format) {
415          case HAL_PIXEL_FORMAT_RGBA_8888:
416          case HAL_PIXEL_FORMAT_RGBX_8888:
417          case HAL_PIXEL_FORMAT_BGRA_8888:
418              size = alignedw * alignedh * 4;
419              break;
420          case HAL_PIXEL_FORMAT_RGB_888:
421              size = alignedw * alignedh * 3;
422              break;
423          case HAL_PIXEL_FORMAT_RGB_565:
424          case HAL_PIXEL_FORMAT_RAW16:
425              size = alignedw * alignedh * 2;
426              break;
427  
428              // adreno formats
429          case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
430              size  = ALIGN(alignedw*alignedh, 4096);
431              size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
432              break;
433          case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
434              // The chroma plane is subsampled,
435              // but the pitch in bytes is unchanged
436              // The GPU needs 4K alignment, but the video decoder needs 8K
437              size  = ALIGN( alignedw * alignedh, 8192);
438              size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
439              break;
440          case HAL_PIXEL_FORMAT_YV12:
441              if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
442                  ALOGE("w or h is odd for the YV12 format");
443                  return 0;
444              }
445              size = alignedw*alignedh +
446                      (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
447              size = ALIGN(size, (unsigned int)4096);
448              break;
449          case HAL_PIXEL_FORMAT_YCbCr_420_SP:
450          case HAL_PIXEL_FORMAT_YCrCb_420_SP:
451              size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
452              break;
453          case HAL_PIXEL_FORMAT_YCbCr_422_SP:
454          case HAL_PIXEL_FORMAT_YCrCb_422_SP:
455          case HAL_PIXEL_FORMAT_YCbCr_422_I:
456          case HAL_PIXEL_FORMAT_YCrCb_422_I:
457              if(width & 1) {
458                  ALOGE("width is odd for the YUV422_SP format");
459                  return 0;
460              }
461              size = ALIGN(alignedw * alignedh * 2, 4096);
462              break;
463          case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
464          case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
465              size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
466              break;
467          case HAL_PIXEL_FORMAT_BLOB:
468              if(height != 1) {
469                  ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
470                        must have height==1 ", __FUNCTION__);
471                  return 0;
472              }
473              size = width;
474              break;
475          case HAL_PIXEL_FORMAT_NV21_ZSL:
476              size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
477              break;
478          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
479          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
480          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
481          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
482          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
483          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
484          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
485          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
486          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
487          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
488          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
489          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
490          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
491          case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
492          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
493          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
494          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
495          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
496          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
497          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
498          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
499          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
500          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
501          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
502          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
503          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
504          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
505          case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
506              size = alignedw * alignedh * ASTC_BLOCK_SIZE;
507              break;
508          default:
509              ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
510              return 0;
511      }
512      return size;
513  }
514  
getBufferSizeAndDimensions(int width,int height,int format,int & alignedw,int & alignedh)515  unsigned int getBufferSizeAndDimensions(int width, int height, int format,
516          int& alignedw, int &alignedh)
517  {
518      unsigned int size;
519  
520      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
521              height,
522              format,
523              false,
524              alignedw,
525              alignedh);
526  
527      size = getSize(format, width, height, alignedw, alignedh);
528  
529      return size;
530  }
531  
532  
getBufferSizeAndDimensions(int width,int height,int format,int usage,int & alignedw,int & alignedh)533  unsigned int getBufferSizeAndDimensions(int width, int height, int format,
534          int usage, int& alignedw, int &alignedh)
535  {
536      unsigned int size;
537      int tileEnabled = isMacroTileEnabled(format, usage);
538  
539      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
540              height,
541              format,
542              tileEnabled,
543              alignedw,
544              alignedh);
545  
546      size = getSize(format, width, height, alignedw, alignedh);
547  
548      return size;
549  }
550  
551  
getBufferAttributes(int width,int height,int format,int usage,int & alignedw,int & alignedh,int & tileEnabled,unsigned int & size)552  void getBufferAttributes(int width, int height, int format, int usage,
553          int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
554  {
555      tileEnabled = isMacroTileEnabled(format, usage);
556  
557      AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
558              height,
559              format,
560              tileEnabled,
561              alignedw,
562              alignedh);
563      size = getSize(format, width, height, alignedw, alignedh);
564  }
565  
getYUVPlaneInfo(private_handle_t * hnd,struct android_ycbcr * ycbcr)566  int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
567  {
568      int err = 0;
569      unsigned int ystride, cstride;
570      memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
571  
572      // Get the chroma offsets from the handle width/height. We take advantage
573      // of the fact the width _is_ the stride
574      switch (hnd->format) {
575          //Semiplanar
576          case HAL_PIXEL_FORMAT_YCbCr_420_SP:
577          case HAL_PIXEL_FORMAT_YCbCr_422_SP:
578          case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
579          case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
580              ystride = cstride = hnd->width;
581              ycbcr->y  = (void*)hnd->base;
582              ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
583              ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
584              ycbcr->ystride = ystride;
585              ycbcr->cstride = cstride;
586              ycbcr->chroma_step = 2;
587          break;
588  
589          case HAL_PIXEL_FORMAT_YCrCb_420_SP:
590          case HAL_PIXEL_FORMAT_YCrCb_422_SP:
591          case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
592          case HAL_PIXEL_FORMAT_NV21_ZSL:
593              ystride = cstride = hnd->width;
594              ycbcr->y  = (void*)hnd->base;
595              ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
596              ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
597              ycbcr->ystride = ystride;
598              ycbcr->cstride = cstride;
599              ycbcr->chroma_step = 2;
600          break;
601  
602          //Planar
603          case HAL_PIXEL_FORMAT_YV12:
604              ystride = hnd->width;
605              cstride = ALIGN(hnd->width/2, 16);
606              ycbcr->y  = (void*)hnd->base;
607              ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
608              ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
609                      cstride * hnd->height/2);
610              ycbcr->ystride = ystride;
611              ycbcr->cstride = cstride;
612              ycbcr->chroma_step = 1;
613  
614          break;
615          //Unsupported formats
616          case HAL_PIXEL_FORMAT_YCbCr_422_I:
617          case HAL_PIXEL_FORMAT_YCrCb_422_I:
618          case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
619          default:
620          ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
621                  hnd->format);
622          err = -EINVAL;
623      }
624      return err;
625  
626  }
627  
628  
629  
630  // Allocate buffer from width, height and format into a
631  // private_handle_t. It is the responsibility of the caller
632  // to free the buffer using the free_buffer function
alloc_buffer(private_handle_t ** pHnd,int w,int h,int format,int usage)633  int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
634  {
635      alloc_data data;
636      int alignedw, alignedh;
637      gralloc::IAllocController* sAlloc =
638          gralloc::IAllocController::getInstance();
639      data.base = 0;
640      data.fd = -1;
641      data.offset = 0;
642      data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
643                                              alignedh);
644  
645      data.align = getpagesize();
646      data.uncached = useUncached(usage);
647      int allocFlags = usage;
648  
649      int err = sAlloc->allocate(data, allocFlags);
650      if (0 != err) {
651          ALOGE("%s: allocate failed", __FUNCTION__);
652          return -ENOMEM;
653      }
654  
655      private_handle_t* hnd = new private_handle_t(data.fd, data.size,
656                                                   data.allocType, 0, format,
657                                                   alignedw, alignedh);
658      hnd->base = (uint64_t) data.base;
659      hnd->offset = data.offset;
660      hnd->gpuaddr = 0;
661      *pHnd = hnd;
662      return 0;
663  }
664  
free_buffer(private_handle_t * hnd)665  void free_buffer(private_handle_t *hnd)
666  {
667      gralloc::IAllocController* sAlloc =
668          gralloc::IAllocController::getInstance();
669      if (hnd && hnd->fd > 0) {
670          IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
671          memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
672      }
673      if(hnd)
674          delete hnd;
675  
676  }
677