alloc_controller.cpp revision 16dd9dfb184ed98c623770819418e168600b29c9
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.
10731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis    if (format < 0x7) {
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            case HAL_PIXEL_FORMAT_RGBA_5551:
11631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_RGBA_4444:
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:
1359f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            case HAL_PIXEL_FORMAT_RAW_SENSOR:
13631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 32);
13731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
13831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
13931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 128);
14031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
14231d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
14331d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
14431d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YV12:
14531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
14631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
14731d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = ALIGN(width, 16);
14831d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
14931d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
15031d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
15131d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis                break;
1529f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            case HAL_PIXEL_FORMAT_BLOB:
1539f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                stride = width;
1549f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                break;
15531d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis            default: break;
15631d8eebf849f5ccce6d6f4fa7b349713d4b1d73dNaomi Luis        }
157bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    }
158bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    return stride;
159bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis}
160bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis
161bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis//-------------- IAllocController-----------------------//
16201d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::sController = NULL;
16301d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::getInstance(void)
164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(sController == NULL) {
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sController = new IonController();
167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return sController;
169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//-------------- IonController-----------------------//
173202a77d28ac251545f6f998a974690212309b927Iliyan MalchevIonController::IonController()
174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
175202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    mIonAlloc = new IonAlloc();
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
17801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedint IonController::allocate(alloc_data& data, int usage)
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ionFlags = 0;
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ret;
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.uncached = useUncached(usage);
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.allocType = 0;
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1898dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1928dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
1958dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    //MM Heap is exclusively a secure heap.
1968dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
1978dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        //XXX: Right now the MM heap is the only secure heap we have. When we
1988dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        //have other secure heaps, we can change this.
1998dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        if(usage & GRALLOC_USAGE_PROTECTED) {
2008dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
2018dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_SECURE;
2028dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        }
2038dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        else {
2048dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
2058dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed                  cannot be used as an insecure heap!\
2068dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed                  trying to use IOMMU instead !!");
2078dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed            ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
2088dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed        }
2098dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    }
210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
2148dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed    if(usage & GRALLOC_USAGE_PROTECTED)
2158dab7bc01d1e5e0f297494f95e445eb92bc211b7Naseer Ahmed         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if no flags are set, default to
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // SF + IOMMU heaps, so that bypass can work
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we can fall back to system heap if
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we run out.
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(!ionFlags)
222202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.flags = ionFlags;
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    ret = mIonAlloc->alloc_buffer(data);
22629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback
22829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(ret < 0 && canFallback(usage,
229202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                              (ionFlags & ION_SYSTEM_HEAP_ID)))
230202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    {
231202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGW("Falling back to system heap");
232202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
233202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ret = mIonAlloc->alloc_buffer(data);
234202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
235202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
236202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(ret >= 0 ) {
23729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
238202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
239202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
240202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return ret;
241202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
242202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
24301d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIMemAlloc* IonController::getAllocator(int flags)
244202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
245b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed    IMemAlloc* memalloc = NULL;
246202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc = mIonAlloc;
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    } else {
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
255202a77d28ac251545f6f998a974690212309b927Iliyan Malchevsize_t getBufferSizeAndDimensions(int width, int height, int format,
25629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  int& alignedw, int &alignedh)
257202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
258202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    size_t size;
259202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
260bb0862a8db32349e2c1fc14f8287e815dde4d9a7Naomi Luis    alignedw = AdrenoMemInfo::getInstance().getStride(width, format);
261202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedh = ALIGN(height, 32);
262202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (format) {
263202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_8888:
264202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBX_8888:
265202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_BGRA_8888:
266202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 4;
267202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
268202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_888:
269202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 3;
270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_565:
272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_5551:
273202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_4444:
2749f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed        case HAL_PIXEL_FORMAT_RAW_SENSOR:
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
287202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN( alignedw * alignedh, 8192);
288202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
290202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YV12:
292202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
293202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                ALOGE("w or h is odd for the YV12 format");
294202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                return -EINVAL;
295202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedh = height;
297202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // The encoder requires a 2K aligned chroma offset.
299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = ALIGN(alignedw*alignedh, 2048) +
30029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            } else {
302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = alignedw*alignedh +
303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = ALIGN(size, 4096);
306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
307255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
308255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
309255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            alignedh = height;
310255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
311255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed            break;
31229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
31329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
31429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(width & 1) {
31529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("width is odd for the YUV422_SP format");
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
31729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedh = height;
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = ALIGN(alignedw * alignedh * 2, 4096);
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
321d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
322a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
323ecb59a81b4a33871c05ed87328f43c9d5fb5a263Sushil Chauhan            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
324d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan            break;
3259f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed        case HAL_PIXEL_FORMAT_BLOB:
3269f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            if(height != 1) {
3279f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
3289f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                      must have height==1 ", __FUNCTION__);
3299f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed                return -EINVAL;
3309f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            }
3319f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedh = height;
3329f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            alignedw = width;
3339f6e860edc4b13d316c229eb0dd6512b6b581c70Naseer Ahmed            size = width;
33416dd9dfb184ed98c623770819418e168600b29c9Naseer Ahmed            break;
335202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
33629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("unrecognized pixel format: 0x%x", format);
337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
340202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return size;
341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
343202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Allocate buffer from width, height and format into a
344202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// private_handle_t. It is the responsibility of the caller
345202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// to free the buffer using the free_buffer function
346202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
34829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data data;
34929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int alignedw, alignedh;
35001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
35101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
35229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.base = 0;
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.fd = -1;
35429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.offset = 0;
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
35629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.align = getpagesize();
35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.uncached = useUncached(usage);
35829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int allocFlags = usage;
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
36001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
36129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 != err) {
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -ENOMEM;
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
36701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 data.allocType, 0, format,
36801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 alignedw, alignedh);
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->base = (int) data.base;
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->offset = data.offset;
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->gpuaddr = 0;
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *pHnd = hnd;
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
374202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
375202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
376202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid free_buffer(private_handle_t *hnd)
377202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
37801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
37901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
380202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd && hnd->fd > 0) {
38101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
382202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
383202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
384202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(hnd)
385202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        delete hnd;
386202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
387202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
388