alloc_controller.cpp revision a43fb8fce6d9be5577de1e0f49c99bd4fe2f6d44
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>
32202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gralloc_priv.h"
33202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h"
34202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h"
35202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "ionalloc.h"
36202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h"
37a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed#include "comptype.h"
38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
39570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#ifdef VENUS_COLOR_FORMAT
40570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#include <media/msm_media_info.h>
41570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#else
42570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_Y_STRIDE(args...) 0
43570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_Y_SCANLINES(args...) 0
44570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#define VENUS_BUFFER_SIZE(args...) 0
45570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan#endif
46570fa94cc8b7d1bae472a34f0b467c756b6e218aSushil Chauhan
47202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc;
48a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmedusing namespace qdutils;
49202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
50202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//Common functions
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic bool canFallback(int usage, bool triedSystem)
52202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback to system heap when alloc fails unless
54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 1. Composition type is MDP
55202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 2. Alloc from system heap was already tried
56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 3. The heap type is requsted explicitly
57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 4. The heap type is protected
58202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // 5. The buffer is meant for external display only
59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
60a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed    if(QCCompositionType::getInstance().getCompositionType() &
61a87da60090f55b823ee999930b381daa3dbda67eNaseer Ahmed       COMPOSITION_TYPE_MDP)
62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(triedSystem)
64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
65e94e0aa7e7259138ffe895bcd9daaa5bde9eafa5Sushil Chauhan    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
674c588a200c537224d4eb5f63fb0a88f791511ff2Naseer Ahmed    if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
68202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    //Return true by default
70202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return true;
71202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
72202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
73202a77d28ac251545f6f998a974690212309b927Iliyan Malchevstatic bool useUncached(int usage)
74202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
75202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // System heaps cannot be uncached
76202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & (GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |
77202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP))
78202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return false;
79202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (usage & GRALLOC_USAGE_PRIVATE_UNCACHED)
80202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        return true;
81202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return false;
82202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
83202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
8401d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::sController = NULL;
8501d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIAllocController* IAllocController::getInstance(void)
86202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
87202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(sController == NULL) {
88202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        sController = new IonController();
89202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
90202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return sController;
91202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
92202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
93202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
94202a77d28ac251545f6f998a974690212309b927Iliyan Malchev//-------------- IonController-----------------------//
95202a77d28ac251545f6f998a974690212309b927Iliyan MalchevIonController::IonController()
96202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
97202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    mIonAlloc = new IonAlloc();
98202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
99202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
10001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedint IonController::allocate(alloc_data& data, int usage)
101202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
102202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ionFlags = 0;
103202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    int ret;
104202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    bool noncontig = false;
105202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
106202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.uncached = useUncached(usage);
10729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.allocType = 0;
10829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
109202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
110202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
111202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
112202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) {
113202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
114202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        noncontig = true;
115202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
116202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
117aec443c5aa263e98032bd1d8b65a46e37b26a4e8Naseer Ahmed    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP) {
118202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
119aec443c5aa263e98032bd1d8b65a46e37b26a4e8Naseer Ahmed        noncontig = true;
120aec443c5aa263e98032bd1d8b65a46e37b26a4e8Naseer Ahmed    }
121202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
122202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)
123202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
124202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
125202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
126202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
127202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
128aec443c5aa263e98032bd1d8b65a46e37b26a4e8Naseer Ahmed    if(usage & GRALLOC_USAGE_PROTECTED && !noncontig)
129202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags |= ION_SECURE;
130202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
131202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // if no flags are set, default to
132202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // SF + IOMMU heaps, so that bypass can work
133202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we can fall back to system heap if
134202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // we run out.
135202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(!ionFlags)
136202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
137202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
138202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    data.flags = ionFlags;
139202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    ret = mIonAlloc->alloc_buffer(data);
14029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
141202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    // Fallback
14229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(ret < 0 && canFallback(usage,
143202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                              (ionFlags & ION_SYSTEM_HEAP_ID)))
144202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    {
145202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGW("Falling back to system heap");
146202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
147202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        noncontig = true;
148202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ret = mIonAlloc->alloc_buffer(data);
149202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
151202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(ret >= 0 ) {
15229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
153202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if(noncontig)
154202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            data.allocType |= private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM;
155202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        if(ionFlags & ION_SECURE)
156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
157202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
158202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
159202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return ret;
160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
161202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
16201d3fd3318a767e6ba75492ed08d57896df95d63Naseer AhmedIMemAlloc* IonController::getAllocator(int flags)
163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
164b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed    IMemAlloc* memalloc = NULL;
165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
166202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc = mIonAlloc;
167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    } else {
168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return memalloc;
172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
174202a77d28ac251545f6f998a974690212309b927Iliyan Malchevsize_t getBufferSizeAndDimensions(int width, int height, int format,
17529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  int& alignedw, int &alignedh)
176202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
177202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    size_t size;
178202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
179202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedw = ALIGN(width, 32);
180202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    alignedh = ALIGN(height, 32);
181202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    switch (format) {
182202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_8888:
183202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBX_8888:
184202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_BGRA_8888:
185202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 4;
186202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
187202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_888:
188202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 3;
189202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
190202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGB_565:
191202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_5551:
192202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_RGBA_4444:
193202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = alignedw * alignedh * 2;
194202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
195202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
196202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // adreno formats
197202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
198202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN(alignedw*alignedh, 4096);
199202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
200202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
201202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
202202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The chroma plane is subsampled,
203202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // but the pitch in bytes is unchanged
204202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            // The GPU needs 4K alignment, but the video decoder needs 8K
205202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedw = ALIGN(width, 128);
206202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size  = ALIGN( alignedw * alignedh, 8192);
207202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
208202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
209202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
210202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
211202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
212202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        case HAL_PIXEL_FORMAT_YV12:
213202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
214202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                ALOGE("w or h is odd for the YV12 format");
215202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                return -EINVAL;
216202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
217202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedw = ALIGN(width, 16);
218202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            alignedh = height;
219202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
220202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                // The encoder requires a 2K aligned chroma offset.
221202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = ALIGN(alignedw*alignedh, 2048) +
22229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
223202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            } else {
224202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                size = alignedw*alignedh +
225202a77d28ac251545f6f998a974690212309b927Iliyan Malchev                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
226202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            }
227202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            size = ALIGN(size, 4096);
228202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            break;
22929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
23029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
23129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(width & 1) {
23229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("width is odd for the YUV422_SP format");
23329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
23429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
23529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedw = ALIGN(width, 16);
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alignedh = height;
23729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = ALIGN(alignedw * alignedh * 2, 4096);
23829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
239d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
240a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedw = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
241a3a6f79dcb8a0cdb2e9a703db66e3d8438a32ce4Sushil Chauhan            alignedh = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
242ecb59a81b4a33871c05ed87328f43c9d5fb5a263Sushil Chauhan            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
243d28fbcbdca035d5ca238aeba5628add89172c573Sushil Chauhan            break;
244202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        default:
24529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("unrecognized pixel format: 0x%x", format);
246202a77d28ac251545f6f998a974690212309b927Iliyan Malchev            return -EINVAL;
247202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    return size;
250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// Allocate buffer from width, height and format into a
253202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// private_handle_t. It is the responsibility of the caller
254202a77d28ac251545f6f998a974690212309b927Iliyan Malchev// to free the buffer using the free_buffer function
255202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
256202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data data;
25829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int alignedw, alignedh;
25901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
26001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
26129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.base = 0;
26229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.fd = -1;
26329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.offset = 0;
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.align = getpagesize();
26629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.uncached = useUncached(usage);
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int allocFlags = usage;
26829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
27029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 != err) {
27129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
27229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -ENOMEM;
27329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
27529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
27601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 data.allocType, 0, format,
27701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed                                                 alignedw, alignedh);
27829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->base = (int) data.base;
27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->offset = data.offset;
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hnd->gpuaddr = 0;
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *pHnd = hnd;
28229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
283202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
284202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
285202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid free_buffer(private_handle_t *hnd)
286202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{
28701d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    gralloc::IAllocController* sAlloc =
28801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        gralloc::IAllocController::getInstance();
289202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if (hnd && hnd->fd > 0) {
29001d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
291202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
292202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    }
293202a77d28ac251545f6f998a974690212309b927Iliyan Malchev    if(hnd)
294202a77d28ac251545f6f998a974690212309b927Iliyan Malchev        delete hnd;
295202a77d28ac251545f6f998a974690212309b927Iliyan Malchev
296202a77d28ac251545f6f998a974690212309b927Iliyan Malchev}
297