1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*
2a43fb8fce6d9be5577de1e0f49c99bd4fe2f6d44Duy Truong * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
3202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
4202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Redistribution and use in source and binary forms, with or without
5202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * modification, are permitted provided that the following conditions are
6202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * met:
7202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *   * Redistributions of source code must retain the above copyright
8202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     notice, this list of conditions and the following disclaimer.
9202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *   * Redistributions in binary form must reproduce the above
10202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     copyright notice, this list of conditions and the following
11202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     disclaimer in the documentation and/or other materials provided
12202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     with the distribution.
13a43fb8fce6d9be5577de1e0f49c99bd4fe2f6d44Duy Truong *   * Neither the name of The Linux Foundation nor the names of its
14202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     contributors may be used to endorse or promote products derived
15202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *     from this software without specific prior written permission.
16202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *
17202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */
29202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
30202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/log.h>
31202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <fcntl.h>
3231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis#include <dlfcn.h>
33202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h"
34202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h"
35202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h"
36202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "ionalloc.h"
37202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h"
38a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed#include "comptype.h"
39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
40570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#ifdef VENUS_COLOR_FORMAT
41570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#include <media/msm_media_info.h>
42570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#else
43570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_Y_STRIDE(args...) 0
44570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_Y_SCANLINES(args...) 0
45570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_BUFFER_SIZE(args...) 0
46570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#endif
47570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan
48202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc;
49a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmedusing namespace qdutils;
50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
51bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi LuisANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
52bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//Common functions
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic bool canFallback(int usage, bool triedSystem)
55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback to system heap when alloc fails unless
57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 1. Composition type is MDP
58202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 2. Alloc from system heap was already tried
59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 3. The heap type is requsted explicitly
60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 4. The heap type is protected
61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 5. The buffer is meant for external display only
62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
63a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed    if(QCCompositionType::getInstance().getCompositionType() &
64a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed       COMPOSITION_TYPE_MDP)
65202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(triedSystem)
67202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
68e94e0aa7e7259138ffe895bcd9daaa5bde9eafa5Sushil Chauhan    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
704c588a200c537224d4eb5f63fb0a88f791511ff2Naseer Ahmed    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    //Return true by default
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return true;
74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
76202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic bool useUncached(int usage)
77202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
78871638fa5f5e2d15314af163f164a297df58e9ecNaseer Ahmed    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
79871638fa5f5e2d15314af163f164a297df58e9ecNaseer Ahmed        return true;
80871638fa5f5e2d15314af163f164a297df58e9ecNaseer Ahmed    if(((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY)
81871638fa5f5e2d15314af163f164a297df58e9ecNaseer Ahmed       ||((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY))
82202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return true;
83202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return false;
84202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
85202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
86bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- AdrenoMemInfo-----------------------//
8731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi LuisAdrenoMemInfo::AdrenoMemInfo()
8831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis{
8931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
9031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    if (libadreno_utils) {
9131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
9231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                           "compute_surface_padding");
9331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    }
9431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis}
9531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis
9631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi LuisAdrenoMemInfo::~AdrenoMemInfo()
9731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis{
9831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    if (libadreno_utils) {
9931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        ::dlclose(libadreno_utils);
10031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    }
10131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis}
10231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis
103bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luisint AdrenoMemInfo::getStride(int width, int format)
104bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis{
105bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    int stride = ALIGN(width, 32);
10631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    // Currently surface padding is only computed for RGB* surfaces.
107277c3f1bc1ae90749ab5fbbf7225b578bcf4fb79Jesse Hall    if (format <= HAL_PIXEL_FORMAT_sRGB_X_8888) {
1081e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis        // Don't add any additional padding if debug.gralloc.map_fb_memory
1091e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis        // is enabled
1101e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis        char property[PROPERTY_VALUE_MAX];
1111e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis        if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
1121e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis           (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
1131e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis           (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
1141e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis              return stride;
1151e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis        }
1161e562641957290401a9a78c73fbc5e22ce753c6fNaomi Luis
11731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        int bpp = 4;
11831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch(format)
11931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
12031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_888:
12131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 3;
12231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
12331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_565:
12431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 2;
12531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
12631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
12731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
12831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        if ((libadreno_utils) && (LINK_adreno_compute_padding)) {
12931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int surface_tile_height = 1;   // Linear surface
130bc082b71d620f3e656169ada5d8a570be19cca5cNaomi Luis            int raster_mode         = 0;   // Adreno unknown raster mode.
13131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int padding_threshold   = 512; // Threshold for padding surfaces.
13231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // the function below expects the width to be a multiple of
13331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // 32 pixels, hence we pass stride instead of width.
13431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            stride = LINK_adreno_compute_padding(stride, bpp,
13531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      surface_tile_height, raster_mode,
13631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      padding_threshold);
13731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
13831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    } else {
13931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch (format)
14031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
14131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
14231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 32);
14331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
14531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 128);
14631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
14831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
14931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YV12:
15031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
15131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1529c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW16:
1539c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
15431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 16);
15531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
15631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
157c46e4be02488b094fe8e310c71077a2cd39da59aNaseer Ahmed            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
15831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
15931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
1609f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            case HAL_PIXEL_FORMAT_BLOB:
1619f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                stride = width;
1629f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                break;
163f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed            case HAL_PIXEL_FORMAT_NV21_ZSL:
164f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed                stride = ALIGN(width, 64);
165f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed                break;
16631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
16731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
168bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    }
169bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    return stride;
170bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis}
171bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
172bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- IAllocController-----------------------//
17301d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::sController = NULL;
17401d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::getInstance(void)
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(sController == NULL) {
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sController = new IonController();
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return sController;
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//-------------- IonController-----------------------//
184202a77d28ac251545f6f998a974690212309b927Iliyan MalchevIonController::IonController()
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    mIonAlloc = new IonAlloc();
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
18901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedint IonController::allocate(alloc_data& data, int usage)
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ionFlags = 0;
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ret;
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.uncached = useUncached(usage);
19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.allocType = 0;
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
197202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
2008dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
201202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
202202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
2038dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
20623622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula    if(usage & GRALLOC_USAGE_PROTECTED) {
207873a69a63909b570e687817ac61684fb4a199c28Naseer Ahmed        if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
2088dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
2098dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_SECURE;
21023622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula        } else {
21123622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula            // for targets/OEMs which do not need HW level protection
212873a69a63909b570e687817ac61684fb4a199c28Naseer Ahmed            // do not set ion secure flag & MM heap. Fallback to IOMMU heap
213873a69a63909b570e687817ac61684fb4a199c28Naseer Ahmed            // and use DRM for such buffers
214873a69a63909b570e687817ac61684fb4a199c28Naseer Ahmed            data.allocType |= private_handle_t::PRIV_FLAGS_L3_SECURE_BUFFER;
2158dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
2168dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        }
21723622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula    } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
21823622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula        //MM Heap is exclusively a secure heap.
21923622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula        //If it is used for non secure cases, fallback to IOMMU heap
22023622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula        ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
22123622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula                                cannot be used as an insecure heap!\
22223622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula                                trying to use IOMMU instead !!");
22323622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
2248dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    }
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
226c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
227c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
228c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R
2299e3f687533fdaecf6f382391a09583a6975dba0bArun Kumar K.R    if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
2309e3f687533fdaecf6f382391a09583a6975dba0bArun Kumar K.R        ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
23223622efd7887587424828b569629df2d85d8597bPrabhanjan Kandula    if(ionFlags & ION_SECURE)
2338dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
235202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if no flags are set, default to
236202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // SF + IOMMU heaps, so that bypass can work
237202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we can fall back to system heap if
238202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we run out.
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(!ionFlags)
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
242202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.flags = ionFlags;
243202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    ret = mIonAlloc->alloc_buffer(data);
24429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
245202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback
24629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(ret < 0 && canFallback(usage,
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                              (ionFlags & ION_SYSTEM_HEAP_ID)))
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    {
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGW("Falling back to system heap");
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ret = mIonAlloc->alloc_buffer(data);
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(ret >= 0 ) {
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
257202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return ret;
259202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
260202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
26101d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIMemAlloc* IonController::getAllocator(int flags)
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
263b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed    IMemAlloc* memalloc = NULL;
264202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
265202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc = mIonAlloc;
266202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    } else {
267202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
268202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
269202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
273202a77d28ac251545f6f998a974690212309b927Iliyan Malchevsize_t getBufferSizeAndDimensions(int width, int height, int format,
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  int& alignedw, int &alignedh)
275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
276202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    size_t size;
277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
278bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
279202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedh = ALIGN(height, 32);
280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (format) {
281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_8888:
282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBX_8888:
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_BGRA_8888:
28432c2c1b1490e949a15dca9351f213d91be2b79d5Naseer Ahmed        case HAL_PIXEL_FORMAT_sRGB_A_8888:
285277c3f1bc1ae90749ab5fbbf7225b578bcf4fb79Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_X_8888:
286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 4;
287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_888:
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 3;
290202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_565:
2929c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang        case HAL_PIXEL_FORMAT_RAW16:
2939c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
294202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 2;
295202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
297202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // adreno formats
298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN(alignedw*alignedh, 4096);
300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The chroma plane is subsampled,
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // but the pitch in bytes is unchanged
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The GPU needs 4K alignment, but the video decoder needs 8K
306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN( alignedw * alignedh, 8192);
307202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YV12:
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                ALOGE("w or h is odd for the YV12 format");
312202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                return -EINVAL;
313202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
314202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedh = height;
315c46e4be02488b094fe8e310c71077a2cd39da59aNaseer Ahmed            size = alignedw*alignedh +
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
317202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = ALIGN(size, 4096);
318202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
319255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
320255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
321255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            alignedh = height;
322073830dc96c3d434bdc24a9ca23a7479fa9de19fNaseer Ahmed            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
323255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            break;
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(width & 1) {
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("width is odd for the YUV422_SP format");
32829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
32929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
33029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedh = height;
33129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = ALIGN(alignedw * alignedh * 2, 4096);
33229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
333d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
334c46e4be02488b094fe8e310c71077a2cd39da59aNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
335a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
336ecb59a81b4a33871c05ed87328f43c9d5fb5a263Sushil Chauhan            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
337d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan            break;
3389f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed        case HAL_PIXEL_FORMAT_BLOB:
3399f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            if(height != 1) {
3409f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
3419f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                      must have height==1 ", __FUNCTION__);
3429f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                return -EINVAL;
3439f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            }
3449f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedh = height;
3459f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedw = width;
3469f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            size = width;
34716dd9dfb184ed98c623770819418e168600b29c9Naseer Ahmed            break;
348f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV21_ZSL:
349f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed            alignedh = ALIGN(height, 64);
350f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
351f0dca604ef4041bb6f839c35ce297ed1d5558e3cNaseer Ahmed            break;
352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("unrecognized pixel format: 0x%x", format);
354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
355202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
356202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
357202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return size;
358202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
359202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
360202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Allocate buffer from width, height and format into a
361202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// private_handle_t. It is the responsibility of the caller
362202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// to free the buffer using the free_buffer function
363202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
364202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data data;
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int alignedw, alignedh;
36701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
36801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.base = 0;
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.fd = -1;
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.offset = 0;
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.align = getpagesize();
37429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.uncached = useUncached(usage);
37529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int allocFlags = usage;
37629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
37701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
37829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 != err) {
37929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
38029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -ENOMEM;
38129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
38229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
38329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
38401d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 data.allocType, 0, format,
38501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 alignedw, alignedh);
38629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->base = (int) data.base;
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->offset = data.offset;
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->gpuaddr = 0;
38929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *pHnd = hnd;
39029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
391202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
392202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
393202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid free_buffer(private_handle_t *hnd)
394202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
39501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
39601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
397202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd && hnd->fd > 0) {
39801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
399202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
400202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
401202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(hnd)
402202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        delete hnd;
403202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
404202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
405