1ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/*
2ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Copyright (C) 2010 The Android Open Source Project
315c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
4ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
5ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Licensed under the Apache License, Version 2.0 (the "License");
6ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * you may not use this file except in compliance with the License.
7ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * You may obtain a copy of the License at
8ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
9ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *      http://www.apache.org/licenses/LICENSE-2.0
10ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
11ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Unless required by applicable law or agreed to in writing, software
12ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * distributed under the License is distributed on an "AS IS" BASIS,
13ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * See the License for the specific language governing permissions and
15ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * limitations under the License.
16ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */
17ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
18ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <limits.h>
19ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <unistd.h>
20ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <fcntl.h>
21ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <cutils/properties.h>
22ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <sys/mman.h>
23ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
24ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "gr.h"
25ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "gpu.h"
26ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "memalloc.h"
27ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "alloc_controller.h"
28ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <qdMetaData.h>
29ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
30ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonusing namespace gralloc;
31ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
32ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define SZ_1M 0x100000
33ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
34ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsongpu_context_t::gpu_context_t(const private_module_t* module,
35ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                             IAllocController* alloc_ctrl ) :
36ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    mAllocCtrl(alloc_ctrl)
37ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
38ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // Zero out the alloc_device_t
39ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
40ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
41ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // Initialize the procs
42ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    common.tag     = HARDWARE_DEVICE_TAG;
43ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    common.version = 0;
44ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    common.module  = const_cast<hw_module_t*>(&module->base.common);
45ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    common.close   = gralloc_close;
46ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    alloc          = gralloc_alloc;
47ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#ifdef QCOM_BSP
48ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    allocSize      = gralloc_alloc_size;
49ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#endif
50ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    free           = gralloc_free;
51ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
52ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
53ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
5492e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shahint gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
55ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                        buffer_handle_t* pHandle, int bufferType,
56ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                        int format, int width, int height)
57ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
58ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int err = 0;
59ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int flags = 0;
60ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    size = roundUpToPageSize(size);
61ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    alloc_data data;
62ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    data.offset = 0;
63ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    data.fd = -1;
64ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    data.base = 0;
65ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
66ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        data.align = 8192;
67ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    else
68ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        data.align = getpagesize();
69ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
70ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    /* force 1MB alignment selectively for secure buffers, MDP5 onwards */
71ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#ifdef MDSS_TARGET
72ec42793abca6c52cf78f748c93632ea73ae1cba6Praveena Pachipulusu    if ((usage & GRALLOC_USAGE_PROTECTED) &&
73ec42793abca6c52cf78f748c93632ea73ae1cba6Praveena Pachipulusu        (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
7415c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R        data.align = ALIGN((int) data.align, SZ_1M);
75ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        size = ALIGN(size, data.align);
76ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
77ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#endif
78ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
79ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    data.size = size;
8015c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R    data.pHandle = (uintptr_t) pHandle;
81ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    err = mAllocCtrl->allocate(data, usage);
82ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
83ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!err) {
84ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        /* allocate memory for enhancement data */
85ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        alloc_data eData;
86ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.fd = -1;
87ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.base = 0;
88ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.offset = 0;
89ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
90ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.pHandle = data.pHandle;
91ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        eData.align = getpagesize();
92ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
93ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
94ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
95ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                          strerror(-eDataErr));
96ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
97ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
98ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
99ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
100ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
10138848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed        ColorSpace_t colorSpace = ITU_R_601;
10238848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed        flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
103ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (bufferType == BUFFER_TYPE_VIDEO) {
104ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
105ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#ifndef MDSS_TARGET
10638848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                colorSpace = ITU_R_601_FR;
107ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
108ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#else
109ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                // Per the camera spec ITU 709 format should be set only for
110ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                // video encoding.
111ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                // It should be set to ITU 601 full range format for any other
112ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                // camera buffer
113ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                //
114ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
11538848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                    if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
116ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                        flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
11738848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                        colorSpace = ITU_R_709;
11838848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                    } else {
119ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                        flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
12038848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                        colorSpace = ITU_R_601_FR;
12138848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed                    }
122ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                }
123ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#endif
124ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
125ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
126ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
127ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
128ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
129ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
130ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
131ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
132ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
133ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
134ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
135ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
136ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
137ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
138ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
139ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_HW_COMPOSER) {
140ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
141ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
142ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
143ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (usage & GRALLOC_USAGE_HW_TEXTURE) {
144ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
145ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
146ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
147a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
148a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
149a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
150a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
151a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(isMacroTileEnabled(format, usage)) {
152a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
153a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
154a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
1554a7fde21bc0dea152a633521d727dda7d540f262Ramkumar Radhakrishnan        if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
1564a7fde21bc0dea152a633521d727dda7d540f262Ramkumar Radhakrishnan            flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
1574a7fde21bc0dea152a633521d727dda7d540f262Ramkumar Radhakrishnan        }
1584a7fde21bc0dea152a633521d727dda7d540f262Ramkumar Radhakrishnan
159ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        flags |= data.allocType;
16092e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
161ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
162ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                bufferType, format, width, height, eData.fd, eData.offset,
163ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                eBaseAddr);
164ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
165ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hnd->offset = data.offset;
16692e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        hnd->base = (uint64_t)(data.base) + data.offset;
167ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hnd->gpuaddr = 0;
16838848c2e82f5a21a4bceb855106bcb7470994d9aNaseer Ahmed        setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
169ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
170ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        *pHandle = hnd;
171ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
172ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
173ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
174ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
175ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return err;
176ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
177ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
178ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonvoid gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
179ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                                    int *bufferType)
180ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
181ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    *bufferType = BUFFER_TYPE_VIDEO;
182ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
1834ee9ce6a957fbecdc26c9732b6483cc6c5967eeaEino-Ville Talvala    if (inputFormat <= HAL_PIXEL_FORMAT_BGRA_8888) {
184ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // RGB formats
185ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        *bufferType = BUFFER_TYPE_UI;
186ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    } else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) ||
187ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson               (inputFormat == HAL_PIXEL_FORMAT_RG_88)) {
188ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        *bufferType = BUFFER_TYPE_UI;
189ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
190ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
191ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
19215c7eb9ba46119290695b650d23180884f1156faArun Kumar K.Rint gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
193ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                                    buffer_handle_t* pHandle)
194ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
195ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
196ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
197ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // we don't support framebuffer allocations with graphics heap flags
198ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (usage & GRALLOC_HEAP_MASK) {
199ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
200ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
201ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
202ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (m->framebuffer == NULL) {
203ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ALOGE("%s: Invalid framebuffer", __FUNCTION__);
204ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
205ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
206ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
20792e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    const unsigned int bufferMask = m->bufferMask;
208ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const uint32_t numBuffers = m->numBuffers;
20992e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    unsigned int bufferSize = m->finfo.line_length * m->info.yres;
210ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
211ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //adreno needs FB size to be page aligned
212ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    bufferSize = roundUpToPageSize(bufferSize);
213ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
214ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (numBuffers == 1) {
215ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // If we have only one buffer, we never use page-flipping. Instead,
216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // we return a regular buffer which will be memcpy'ed to the main
217ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // screen when post is called.
218ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
219ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
220ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                    m->fbFormat, m->info.xres, m->info.yres);
221ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
222ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
223ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (bufferMask >= ((1LU<<numBuffers)-1)) {
224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // We ran out of buffers.
225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -ENOMEM;
226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // create a "fake" handle for it
22992e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    uint64_t vaddr = uint64_t(m->framebuffer->base);
230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    private_handle_t* hnd = new private_handle_t(
231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dup(m->framebuffer->fd), bufferSize,
232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t::PRIV_FLAGS_USES_PMEM |
233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
234ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
235ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        m->info.yres);
236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
237ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // find a free slot
238ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    for (uint32_t i=0 ; i<numBuffers ; i++) {
239ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if ((bufferMask & (1LU<<i)) == 0) {
240cfb968873b9e94dca883aadabee42b01558faea9Shalaj Jain            m->bufferMask |= (uint32_t)(1LU<<i);
241ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
242ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
243ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        vaddr += bufferSize;
244ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
245ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hnd->base = vaddr;
24692e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    hnd->offset = (unsigned int)(vaddr - m->framebuffer->base);
247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    *pHandle = hnd;
248ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
249ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
250ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
251ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
25215c7eb9ba46119290695b650d23180884f1156faArun Kumar K.Rint gpu_context_t::gralloc_alloc_framebuffer(int usage,
253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                             buffer_handle_t* pHandle)
254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
255ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
256ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    pthread_mutex_lock(&m->lock);
25715c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R    int err = gralloc_alloc_framebuffer_locked(usage, pHandle);
258ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    pthread_mutex_unlock(&m->lock);
259ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return err;
260ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
261ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::alloc_impl(int w, int h, int format, int usage,
263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                              buffer_handle_t* pHandle, int* pStride,
26492e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah                              unsigned int bufferSize) {
265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!pHandle || !pStride)
266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
26892e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    unsigned int size;
269ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int alignedw, alignedh;
270ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int grallocFormat = format;
271ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int bufferType;
272ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
273ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //the usage bits, gralloc assigns a format.
275a37e19093ec1c30dff5d0b5ae9a0938868e537e6Naseer Ahmed    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
276a37e19093ec1c30dff5d0b5ae9a0938868e537e6Naseer Ahmed       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
279ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
280ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                == GRALLOC_USAGE_HW_CAMERA_ZSL)
281ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
282ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
283ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
284ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
285ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
286a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        else if(usage & GRALLOC_USAGE_HW_COMPOSER)
287a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            //XXX: If we still haven't set a format, default to RGBA8888
288a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
2894c9a29a3c5b26bbfebdb8551334c5444e627ce1ePrashant Malani        else if(format == HAL_PIXEL_FORMAT_YCbCr_420_888)
2904c9a29a3c5b26bbfebdb8551334c5444e627ce1ePrashant Malani            // If no other usage flags are detected, default the flexible YUV
2914c9a29a3c5b26bbfebdb8551334c5444e627ce1ePrashant Malani            // format to NV21_ZSL.
2924c9a29a3c5b26bbfebdb8551334c5444e627ce1ePrashant Malani            grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL;
293ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
294ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
295ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    getGrallocInformationFromFormat(grallocFormat, &bufferType);
296a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
297a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                   alignedh);
298ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
29992e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah    if ((unsigned int)size <= 0)
300ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
301ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    size = (bufferSize >= size)? bufferSize : size;
302ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
303ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    bool useFbMem = false;
304ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    char property[PROPERTY_VALUE_MAX];
305ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if((usage & GRALLOC_USAGE_HW_FB) &&
306ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson       (property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        useFbMem = true;
310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
311ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
312ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int err = 0;
313ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(useFbMem) {
31415c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R        err = gralloc_alloc_framebuffer(usage, pHandle);
315ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    } else {
316ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
317ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                   grallocFormat, alignedw, alignedh);
318ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
319ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
320ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (err < 0) {
321ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return err;
322ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
323ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
324ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    *pStride = alignedw;
325ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
326ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
327ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
328ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::free_impl(private_handle_t const* hnd) {
329ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
330ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
33192e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        const unsigned int bufferSize = m->finfo.line_length * m->info.yres;
33292e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        unsigned int index = (unsigned int) ((hnd->base - m->framebuffer->base)
33392e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah                / bufferSize);
334cfb968873b9e94dca883aadabee42b01558faea9Shalaj Jain        m->bufferMask &= (uint32_t)~(1LU<<index);
335ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    } else {
336ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
337ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
338ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
33992e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        int err = memalloc->free_buffer((void*)hnd->base, hnd->size,
340ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                        hnd->offset, hnd->fd);
341ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(err)
342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            return err;
343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // free the metadata space
34492e456fd92a6231dbf5d9de5289ed2f84841a804Saurabh Shah        unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        err = memalloc->free_buffer((void*)hnd->base_metadata,
34615c7eb9ba46119290695b650d23180884f1156faArun Kumar K.R                                    size, hnd->offset_metadata,
347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                    hnd->fd_metadata);
348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (err)
349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            return err;
350ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
351ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    delete hnd;
352ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
353ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
354ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
355ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                 int usage, buffer_handle_t* pHandle,
357ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                 int* pStride)
358ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
359ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!dev) {
360ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
361ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
362ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
363ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0);
364ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
365ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h,
366ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                      int format, int usage,
367ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                      buffer_handle_t* pHandle, int* pStride,
368ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                      int bufferSize)
369ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
370ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!dev) {
371ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
372ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
373ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
374ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize);
375ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
376ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
377ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
378ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::gralloc_free(alloc_device_t* dev,
379ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                                buffer_handle_t handle)
380ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
381ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (private_handle_t::validate(handle) < 0)
382ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
383ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
384ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
385ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
386ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return gpu->free_impl(hnd);
387ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
388ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
389ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/*****************************************************************************/
390ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
391ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint gpu_context_t::gralloc_close(struct hw_device_t *dev)
392ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
393ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev);
394ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (ctx) {
395ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        /* TODO: keep a list of all buffer_handle_t created, and free them
396ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson         * all here.
397ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson         */
398ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        delete ctx;
399ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
400ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
401ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
402