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 <cutils/properties.h>
32#include <dlfcn.h>
33
34#include "gralloc_priv.h"
35#include "gr_adreno_info.h"
36#include "gr_utils.h"
37
38namespace gralloc1 {
39
40AdrenoMemInfo::AdrenoMemInfo() {
41}
42
43bool AdrenoMemInfo::Init() {
44  libadreno_utils_ = ::dlopen("libadreno_utils.so", RTLD_NOW);
45  if (libadreno_utils_) {
46    *reinterpret_cast<void **>(&LINK_adreno_compute_aligned_width_and_height) =
47        ::dlsym(libadreno_utils_, "compute_aligned_width_and_height");
48    *reinterpret_cast<void **>(&LINK_adreno_compute_padding) =
49        ::dlsym(libadreno_utils_, "compute_surface_padding");
50    *reinterpret_cast<void **>(&LINK_adreno_compute_compressedfmt_aligned_width_and_height) =
51        ::dlsym(libadreno_utils_, "compute_compressedfmt_aligned_width_and_height");
52    *reinterpret_cast<void **>(&LINK_adreno_isUBWCSupportedByGpu) =
53        ::dlsym(libadreno_utils_, "isUBWCSupportedByGpu");
54    *reinterpret_cast<void **>(&LINK_adreno_get_gpu_pixel_alignment) =
55        ::dlsym(libadreno_utils_, "get_gpu_pixel_alignment");
56  } else {
57    ALOGW(" Failed to load libadreno_utils.so");
58  }
59
60  // Check if the overriding property debug.gralloc.gfx_ubwc_disable_
61  // that disables UBWC allocations for the graphics stack is set
62  char property[PROPERTY_VALUE_MAX];
63  property_get("debug.gralloc.gfx_ubwc_disable_", property, "0");
64  if (!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
65      !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
66    gfx_ubwc_disable_ = true;
67  }
68
69  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
70      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
71       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
72    map_fb_ = true;
73  }
74
75  return true;
76}
77
78AdrenoMemInfo::~AdrenoMemInfo() {
79  if (libadreno_utils_) {
80    ::dlclose(libadreno_utils_);
81  }
82}
83
84void AdrenoMemInfo::AlignUnCompressedRGB(int width, int height, int format, int tile_enabled,
85                                         unsigned int *aligned_w, unsigned int *aligned_h) {
86  *aligned_w = (unsigned int)ALIGN(width, 32);
87  *aligned_h = (unsigned int)ALIGN(height, 32);
88
89  // Don't add any additional padding if debug.gralloc.map_fb_memory
90  // is enabled
91  if (map_fb_) {
92    return;
93  }
94
95  int bpp = 4;
96  switch (format) {
97    case HAL_PIXEL_FORMAT_RGB_888:
98      bpp = 3;
99      break;
100    case HAL_PIXEL_FORMAT_RGB_565:
101    case HAL_PIXEL_FORMAT_BGR_565:
102    case HAL_PIXEL_FORMAT_RGBA_5551:
103    case HAL_PIXEL_FORMAT_RGBA_4444:
104      bpp = 2;
105      break;
106    default:
107      break;
108  }
109
110  int raster_mode = 0;          // Adreno unknown raster mode.
111  int padding_threshold = 512;  // Threshold for padding surfaces.
112  // the function below computes aligned width and aligned height
113  // based on linear or macro tile mode selected.
114  if (LINK_adreno_compute_aligned_width_and_height) {
115    LINK_adreno_compute_aligned_width_and_height(
116        width, height, bpp, tile_enabled, raster_mode, padding_threshold,
117        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h));
118  } else if (LINK_adreno_compute_padding) {
119    int surface_tile_height = 1;  // Linear surface
120    *aligned_w = UINT(LINK_adreno_compute_padding(width, bpp, surface_tile_height, raster_mode,
121                                                  padding_threshold));
122    ALOGW("%s: Warning!! Old GFX API is used to calculate stride", __FUNCTION__);
123  } else {
124    ALOGW(
125        "%s: Warning!! Symbols compute_surface_padding and "
126        "compute_aligned_width_and_height not found",
127        __FUNCTION__);
128  }
129}
130
131void AdrenoMemInfo::AlignCompressedRGB(int width, int height, int format, unsigned int *aligned_w,
132                                       unsigned int *aligned_h) {
133  if (LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
134    int bytesPerPixel = 0;
135    int raster_mode = 0;          // Adreno unknown raster mode.
136    int padding_threshold = 512;  // Threshold for padding
137    // surfaces.
138
139    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
140        width, height, format, 0, raster_mode, padding_threshold,
141        reinterpret_cast<int *>(aligned_w), reinterpret_cast<int *>(aligned_h), &bytesPerPixel);
142  } else {
143    *aligned_w = (unsigned int)ALIGN(width, 32);
144    *aligned_h = (unsigned int)ALIGN(height, 32);
145    ALOGW("%s: Warning!! compute_compressedfmt_aligned_width_and_height not found", __FUNCTION__);
146  }
147}
148
149bool AdrenoMemInfo::IsUBWCSupportedByGPU(int format) {
150  if (!gfx_ubwc_disable_ && LINK_adreno_isUBWCSupportedByGpu) {
151    ADRENOPIXELFORMAT gpu_format = GetGpuPixelFormat(format);
152    return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
153  }
154
155  return false;
156}
157
158uint32_t AdrenoMemInfo::GetGpuPixelAlignment() {
159  if (LINK_adreno_get_gpu_pixel_alignment) {
160    return LINK_adreno_get_gpu_pixel_alignment();
161  }
162
163  return 1;
164}
165
166ADRENOPIXELFORMAT AdrenoMemInfo::GetGpuPixelFormat(int hal_format) {
167  switch (hal_format) {
168    case HAL_PIXEL_FORMAT_RGBA_8888:
169      return ADRENO_PIXELFORMAT_R8G8B8A8;
170    case HAL_PIXEL_FORMAT_RGBX_8888:
171      return ADRENO_PIXELFORMAT_R8G8B8X8;
172    case HAL_PIXEL_FORMAT_RGB_565:
173      return ADRENO_PIXELFORMAT_B5G6R5;
174    case HAL_PIXEL_FORMAT_BGR_565:
175      return ADRENO_PIXELFORMAT_R5G6B5;
176    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
177      return ADRENO_PIXELFORMAT_NV12;
178    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
179    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
180      return ADRENO_PIXELFORMAT_NV12_EXT;
181    case HAL_PIXEL_FORMAT_RGBA_1010102:
182       return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
183    case HAL_PIXEL_FORMAT_RGBX_1010102:
184       return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
185    case HAL_PIXEL_FORMAT_ABGR_2101010:
186       return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
187    default:
188      ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
189      break;
190  }
191
192  return ADRENO_PIXELFORMAT_UNKNOWN;
193}
194
195}  // namespace gralloc1
196