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{
78202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // System heaps cannot be uncached
793b8977d7f226026afb11e4107d60d455eab45069Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
80202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
81202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
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) {
10831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        int bpp = 4;
10931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch(format)
11031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
11131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_888:
11231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 3;
11331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
11431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGB_565:
11531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                bpp = 2;
11631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
11731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
11831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
11931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        if ((libadreno_utils) && (LINK_adreno_compute_padding)) {
12031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int surface_tile_height = 1;   // Linear surface
121bc082b71d620f3e656169ada5d8a570be19cca5cNaomi Luis            int raster_mode         = 0;   // Adreno unknown raster mode.
12231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            int padding_threshold   = 512; // Threshold for padding surfaces.
12331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // the function below expects the width to be a multiple of
12431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            // 32 pixels, hence we pass stride instead of width.
12531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            stride = LINK_adreno_compute_padding(stride, bpp,
12631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      surface_tile_height, raster_mode,
12731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                                      padding_threshold);
12831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
12931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    } else {
13031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        switch (format)
13131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        {
13231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
13331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 32);
13431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
13531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
13631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 128);
13731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
13831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
13931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
14031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
14131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YV12:
14231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
14331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1449c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW16:
1459c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
14631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 16);
14731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
14931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
15031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
1519f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            case HAL_PIXEL_FORMAT_BLOB:
1529f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                stride = width;
1539f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                break;
15431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
15531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
156bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    }
157bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    return stride;
158bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis}
159bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
160bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- IAllocController-----------------------//
16101d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::sController = NULL;
16201d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::getInstance(void)
163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(sController == NULL) {
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sController = new IonController();
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return sController;
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//-------------- IonController-----------------------//
172202a77d28ac251545f6f998a974690212309b927Iliyan MalchevIonController::IonController()
173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    mIonAlloc = new IonAlloc();
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
17701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedint IonController::allocate(alloc_data& data, int usage)
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ionFlags = 0;
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ret;
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.uncached = useUncached(usage);
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.allocType = 0;
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1888dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1918dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
194513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    //MM Heap is exclusively a secure heap.
195513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
196513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        //XXX: Right now the MM heap is the only secure heap we have. When we
197513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        //have other secure heaps, we can change this.
198513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        if(usage & GRALLOC_USAGE_PROTECTED) {
1998dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
2008dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_SECURE;
201513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        }
202513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        else {
203513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
204513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                  cannot be used as an insecure heap!\
205513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                  trying to use IOMMU instead !!");
2068dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
2078dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        }
2088dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    }
209202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
210c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
211c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
212c5644089c80d57bfbcbe42b20718959068059715Arun Kumar K.R
213513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    if(usage & GRALLOC_USAGE_PROTECTED)
2148dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
215202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if no flags are set, default to
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // SF + IOMMU heaps, so that bypass can work
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we can fall back to system heap if
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we run out.
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(!ionFlags)
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.flags = ionFlags;
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    ret = mIonAlloc->alloc_buffer(data);
22529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback
22729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(ret < 0 && canFallback(usage,
228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                              (ionFlags & ION_SYSTEM_HEAP_ID)))
229202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    {
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGW("Falling back to system heap");
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ret = mIonAlloc->alloc_buffer(data);
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
235202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(ret >= 0 ) {
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
237202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
238202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return ret;
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
24201d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIMemAlloc* IonController::getAllocator(int flags)
243202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
244b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed    IMemAlloc* memalloc = NULL;
245202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
246202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc = mIonAlloc;
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    } else {
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchevsize_t getBufferSizeAndDimensions(int width, int height, int format,
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  int& alignedw, int &alignedh)
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
257202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    size_t size;
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
259bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
260202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedh = ALIGN(height, 32);
261202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (format) {
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_8888:
263202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBX_8888:
264202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_BGRA_8888:
26532c2c1b1490e949a15dca9351f213d91be2b79d5Naseer Ahmed        case HAL_PIXEL_FORMAT_sRGB_A_8888:
266277c3f1bc1ae90749ab5fbbf7225b578bcf4fb79Jesse Hall        case HAL_PIXEL_FORMAT_sRGB_X_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:
2749c043caec3b1a7bf08e9e0fb437ea8f3c2e30ceaShuzhen Wang        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 2;
276202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
278202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // adreno formats
279202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN(alignedw*alignedh, 4096);
281202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
282202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
284202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The chroma plane is subsampled,
285202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // but the pitch in bytes is unchanged
286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The GPU needs 4K alignment, but the video decoder needs 8K
287e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedw = ALIGN(alignedw, 128);
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN( alignedw * alignedh, 8192);
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
290202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
291e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan        case HAL_PIXEL_FORMAT_NV12:
292e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedw = ALIGN(width, 16);
293e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            alignedh = height;
294e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            size  = ALIGN( ALIGN(width, 128) * ALIGN(height, 32), 8192);
295e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            size += ALIGN( ALIGN(width, 128) * ALIGN(height/2, 32), 8192);
296e33bae63cde0b553009cb6907b7ed69acd833c59Praveen Chavan            break;
297202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YV12:
299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                ALOGE("w or h is odd for the YV12 format");
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                return -EINVAL;
302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedh = height;
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // The encoder requires a 2K aligned chroma offset.
306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = ALIGN(alignedw*alignedh, 2048) +
30729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            } else {
309202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = alignedw*alignedh +
310202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
311202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
312202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = ALIGN(size, 4096);
313202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
314255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
315255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
316255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            alignedh = height;
317255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
318255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            break;
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(width & 1) {
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("width is odd for the YUV422_SP format");
32329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedh = height;
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = ALIGN(alignedw * alignedh * 2, 4096);
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
328d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
329a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
330ecb59a81b4a33871c05ed87328f43c9d5fb5a263Sushil Chauhan            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
331d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan            break;
3329f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed        case HAL_PIXEL_FORMAT_BLOB:
3339f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            if(height != 1) {
3349f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
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