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
5173cde9b41ac26449d2155a39078fd3ded3f92f6dBernhard Rosenkränzernamespace android {
52bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi LuisANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
5373cde9b41ac26449d2155a39078fd3ded3f92f6dBernhard Rosenkränzer}
54bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//Common functions
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic bool canFallback(int usage, bool triedSystem)
57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
58202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback to system heap when alloc fails unless
59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 1. Composition type is MDP
60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 2. Alloc from system heap was already tried
61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 3. The heap type is requsted explicitly
62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 4. The heap type is protected
63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 5. The buffer is meant for external display only
64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
65a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed    if(QCCompositionType::getInstance().getCompositionType() &
66a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed       COMPOSITION_TYPE_MDP)
67202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
68202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(triedSystem)
69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
70e94e0aa7e7259138ffe895bcd9daaa5bde9eafa5Sushil Chauhan    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
724c588a200c537224d4eb5f63fb0a88f791511ff2Naseer Ahmed    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    //Return true by default
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return true;
76202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
77202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
78202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic bool useUncached(int usage)
79202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
80202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // System heaps cannot be uncached
813b8977d7f226026afb11e4107d60d455eab45069Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
82202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
83202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
84202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return true;
85202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return false;
86202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
87202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
88bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- AdrenoMemInfo-----------------------//
8931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi LuisAdrenoMemInfo::AdrenoMemInfo()
9031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis{
9131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
9231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    if (libadreno_utils) {
9331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
9431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                           "compute_surface_padding");
9531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    }
9631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis}
9731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis
9831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi LuisAdrenoMemInfo::~AdrenoMemInfo()
9931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis{
10031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    if (libadreno_utils) {
10131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        ::dlclose(libadreno_utils);
10231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    }
10331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis}
10431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis
105bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luisint AdrenoMemInfo::getStride(int width, int format)
106bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis{
107bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    int stride = ALIGN(width, 32);
10831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    // Currently surface padding is only computed for RGB* surfaces.
1094ee9ce6a957fbecdc26c9732b6483cc6c5967eeaEino-Ville Talvala    if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
11031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        int bpp = 4;
11131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch(format)
11231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
11331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_888:
11431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 3;
11531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
11631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_565:
11731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 2;
11831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
11931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
12031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
12131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        if ((libadreno_utils) && (LINK_adreno_compute_padding)) {
12231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int surface_tile_height = 1;   // Linear surface
123bc082b71d620f3e656169ada5d8a570be19cca5cNaomi Luis            int raster_mode         = 0;   // Adreno unknown raster mode.
12431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int padding_threshold   = 512; // Threshold for padding surfaces.
12531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // the function below expects the width to be a multiple of
12631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // 32 pixels, hence we pass stride instead of width.
12731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            stride = LINK_adreno_compute_padding(stride, bpp,
12831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      surface_tile_height, raster_mode,
12931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      padding_threshold);
13031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
13131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    } else {
13231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch (format)
13331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
13431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
13531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 32);
13631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
13731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
13831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 128);
13931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
14131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
14231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
14331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YV12:
14431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
14531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1469c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW16:
1479c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
14831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 16);
14931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
15031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
15131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
15231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
1539f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            case HAL_PIXEL_FORMAT_BLOB:
1549f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                stride = width;
1559f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                break;
15631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
15731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
158bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    }
159bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    return stride;
160bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis}
161bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
162bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- IAllocController-----------------------//
16301d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::sController = NULL;
16401d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::getInstance(void)
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(sController == NULL) {
167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sController = new IonController();
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return sController;
170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//-------------- IonController-----------------------//
174202a77d28ac251545f6f998a974690212309b927Iliyan MalchevIonController::IonController()
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    mIonAlloc = new IonAlloc();
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
17901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedint IonController::allocate(alloc_data& data, int usage)
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ionFlags = 0;
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ret;
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.uncached = useUncached(usage);
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.allocType = 0;
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1908dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1938dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
195202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
196513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    //MM Heap is exclusively a secure heap.
197513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
198513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        //XXX: Right now the MM heap is the only secure heap we have. When we
199513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        //have other secure heaps, we can change this.
200513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        if(usage & GRALLOC_USAGE_PROTECTED) {
2018dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
2028dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_SECURE;
203513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        }
204513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        else {
205513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
206513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                  cannot be used as an insecure heap!\
207513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                  trying to use IOMMU instead !!");
2088dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
2098dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        }
2108dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    }
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
212c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
213c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
214c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R
215513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    if(usage & GRALLOC_USAGE_PROTECTED)
2168dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if no flags are set, default to
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // SF + IOMMU heaps, so that bypass can work
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we can fall back to system heap if
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we run out.
222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(!ionFlags)
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.flags = ionFlags;
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    ret = mIonAlloc->alloc_buffer(data);
22729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback
22929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(ret < 0 && canFallback(usage,
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                              (ionFlags & ION_SYSTEM_HEAP_ID)))
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    {
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGW("Falling back to system heap");
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ret = mIonAlloc->alloc_buffer(data);
235202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
236202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
237202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(ret >= 0 ) {
23829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return ret;
242202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
243202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
24401d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIMemAlloc* IonController::getAllocator(int flags)
245202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
246b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed    IMemAlloc* memalloc = NULL;
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc = mIonAlloc;
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    } else {
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
255202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchevsize_t getBufferSizeAndDimensions(int width, int height, int format,
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  int& alignedw, int &alignedh)
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
259202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    size_t size;
260202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
261bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedh = ALIGN(height, 32);
263202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (format) {
264202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_8888:
265202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBX_8888:
266202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_BGRA_8888:
267202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 4;
268202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
269202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_888:
270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 3;
271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_565:
2739c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang        case HAL_PIXEL_FORMAT_RAW16:
274202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 2;
275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
276202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // adreno formats
278202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
279202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN(alignedw*alignedh, 4096);
280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The chroma plane is subsampled,
284202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // but the pitch in bytes is unchanged
285202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The GPU needs 4K alignment, but the video decoder needs 8K
286e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedw = ALIGN(alignedw, 128);
287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN( alignedw * alignedh, 8192);
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
290e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan        case HAL_PIXEL_FORMAT_NV12:
291e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedw = ALIGN(width, 16);
292e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedh = height;
293e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            size  = ALIGN( ALIGN(width, 128) * ALIGN(height, 32), 8192);
294e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            size += ALIGN( ALIGN(width, 128) * ALIGN(height/2, 32), 8192);
295e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            break;
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
297202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YV12:
298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                ALOGE("w or h is odd for the YV12 format");
300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                return -EINVAL;
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedh = height;
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // The encoder requires a 2K aligned chroma offset.
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = ALIGN(alignedw*alignedh, 2048) +
30629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
307202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            } else {
308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = alignedw*alignedh +
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = ALIGN(size, 4096);
312202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
313255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
314255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
315255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            alignedh = height;
316255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
317255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            break;
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(width & 1) {
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("width is odd for the YUV422_SP format");
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
32329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedh = height;
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = ALIGN(alignedw * alignedh * 2, 4096);
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
327d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
328a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
329ecb59a81b4a33871c05ed87328f43c9d5fb5a263Sushil Chauhan            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
330d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan            break;
3319f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed        case HAL_PIXEL_FORMAT_BLOB:
332b1df9d27dc8e8946934621cc2720725ba0df2dd8Naseer Ahmed        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
3339f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            if(height != 1) {
334b1df9d27dc8e8946934621cc2720725ba0df2dd8Naseer Ahmed                ALOGE("%s: Buffers with RAW_OPAQUE/BLOB formats \
3359f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                      must have height==1 ", __FUNCTION__);
3369f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                return -EINVAL;
3379f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            }
3389f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedh = height;
3399f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedw = width;
3409f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            size = width;
34116dd9dfb184ed98c623770819418e168600b29c9Naseer Ahmed            break;
342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
34329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("unrecognized pixel format: 0x%x", format);
344202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
345202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
346202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return size;
348202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
349202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
350202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Allocate buffer from width, height and format into a
351202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// private_handle_t. It is the responsibility of the caller
352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// to free the buffer using the free_buffer function
353202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data data;
35629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int alignedw, alignedh;
35701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
35801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.base = 0;
36029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.fd = -1;
36129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.offset = 0;
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.align = getpagesize();
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.uncached = useUncached(usage);
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int allocFlags = usage;
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
36701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
36829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 != err) {
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -ENOMEM;
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
37401d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 data.allocType, 0, format,
37501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 alignedw, alignedh);
37629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->base = (int) data.base;
37729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->offset = data.offset;
37829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->gpuaddr = 0;
37929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *pHnd = hnd;
38029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
381202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
382202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
383202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid free_buffer(private_handle_t *hnd)
384202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
38501d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
38601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
387202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd && hnd->fd > 0) {
38801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
389202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
390202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
391202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(hnd)
392202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        delete hnd;
393202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
394202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
395