1202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/* 2202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Copyright (C) 2010 The Android Open Source Project 3aee73e2656d1176ee29d20218947fc3a379818b3Naseer Ahmed * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. 4202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * 5202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 6202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * you may not use this file except in compliance with the License. 7202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * You may obtain a copy of the License at 8202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * 9202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 10202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * 11202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * Unless required by applicable law or agreed to in writing, software 12202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 13202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * See the License for the specific language governing permissions and 15202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * limitations under the License. 16202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 17202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 18202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <limits.h> 19202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <unistd.h> 20202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <fcntl.h> 21202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <cutils/properties.h> 22202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include <sys/mman.h> 23202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 24202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gr.h" 25202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "gpu.h" 26202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "memalloc.h" 27202a77d28ac251545f6f998a974690212309b927Iliyan Malchev#include "alloc_controller.h" 28c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan#include <qdMetaData.h> 29b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan#include "mdp_version.h" 30202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 31202a77d28ac251545f6f998a974690212309b927Iliyan Malchevusing namespace gralloc; 32202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 33b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan#define SZ_1M 0x100000 34b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan 35202a77d28ac251545f6f998a974690212309b927Iliyan Malchevgpu_context_t::gpu_context_t(const private_module_t* module, 3601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed IAllocController* alloc_ctrl ) : 37202a77d28ac251545f6f998a974690212309b927Iliyan Malchev mAllocCtrl(alloc_ctrl) 38202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 39202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // Zero out the alloc_device_t 40202a77d28ac251545f6f998a974690212309b927Iliyan Malchev memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t)); 41202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 42202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // Initialize the procs 43202a77d28ac251545f6f998a974690212309b927Iliyan Malchev common.tag = HARDWARE_DEVICE_TAG; 44202a77d28ac251545f6f998a974690212309b927Iliyan Malchev common.version = 0; 45202a77d28ac251545f6f998a974690212309b927Iliyan Malchev common.module = const_cast<hw_module_t*>(&module->base.common); 46202a77d28ac251545f6f998a974690212309b927Iliyan Malchev common.close = gralloc_close; 47202a77d28ac251545f6f998a974690212309b927Iliyan Malchev alloc = gralloc_alloc; 48da429776b96f9e81aee0b250ab3c0fb9cdcd3254Naseer Ahmed#ifdef QCOM_BSP 49c16e681fb93fc9a91e3224dc79607657f5ede036Ramkumar Radhakrishnan allocSize = gralloc_alloc_size; 50da429776b96f9e81aee0b250ab3c0fb9cdcd3254Naseer Ahmed#endif 51202a77d28ac251545f6f998a974690212309b927Iliyan Malchev free = gralloc_free; 52202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 53202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 54202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 55202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, 56202a77d28ac251545f6f998a974690212309b927Iliyan Malchev buffer_handle_t* pHandle, int bufferType, 57202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int format, int width, int height) 58202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 59202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int err = 0; 60202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int flags = 0; 61202a77d28ac251545f6f998a974690212309b927Iliyan Malchev size = roundUpToPageSize(size); 62202a77d28ac251545f6f998a974690212309b927Iliyan Malchev alloc_data data; 63202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.offset = 0; 64202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.fd = -1; 65202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.base = 0; 66202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) 67202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.align = 8192; 68202a77d28ac251545f6f998a974690212309b927Iliyan Malchev else 69202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.align = getpagesize(); 70b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan 71b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan /* force 1MB alignment selectively for secure buffers, MDP5 onwards */ 72b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan if ((qdutils::MDPVersion::getInstance().getMDPVersion() >= \ 73b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan qdutils::MDSS_V5) && (usage & GRALLOC_USAGE_PROTECTED)) { 74b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan data.align = ALIGN(data.align, SZ_1M); 75b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan size = ALIGN(size, data.align); 76b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan } 77b4dd279bc5044a42a704884be76c5b5f25caf9caPraveen Chavan data.size = size; 78202a77d28ac251545f6f998a974690212309b927Iliyan Malchev data.pHandle = (unsigned int) pHandle; 7901d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed err = mAllocCtrl->allocate(data, usage); 80202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 81c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (!err) { 82c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan /* allocate memory for enhancement data */ 83c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan alloc_data eData; 84c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.fd = -1; 85c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.base = 0; 86c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.offset = 0; 87c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 88c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.pHandle = data.pHandle; 89c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eData.align = getpagesize(); 90c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP; 91c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan int eDataErr = mAllocCtrl->allocate(eData, eDataUsage); 92c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s", 93c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan strerror(-eDataErr)); 94c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan 95c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) { 96c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY; 97c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan //The EXTERNAL_BLOCK flag is always an add-on 98c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_BLOCK) { 99c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_BLOCK; 100c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 101c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_CC) { 102c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_CC; 103c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 104202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 105202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 106e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed if (bufferType == BUFFER_TYPE_VIDEO) { 107e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) { 108e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed if ((qdutils::MDPVersion::getInstance().getMDPVersion() < 109e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed qdutils::MDSS_V5)) { //A-Family 110e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR; 111e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed } else { 112e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed if (usage & (GRALLOC_USAGE_HW_TEXTURE | 113e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed GRALLOC_USAGE_HW_VIDEO_ENCODER)) 114e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed flags |= private_handle_t::PRIV_FLAGS_ITU_R_709; 115e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed else if (usage & GRALLOC_USAGE_HW_CAMERA_ZSL) 116e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR; 117e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed } 118e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed } else { 119e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed flags |= private_handle_t::PRIV_FLAGS_ITU_R_601; 120e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed } 121e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed } 122e4d4d1c2d57885a3a4d23461c317284f232dd3cdNaseer Ahmed 123c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) { 124c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER; 125c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 12659802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed 127c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) { 128c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE; 129c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 13059802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed 131c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan if (usage & GRALLOC_USAGE_HW_CAMERA_READ) { 132c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ; 133c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan } 13459802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed 135ae658e884cc703419ad281d25fa5957db74131ccNaseer Ahmed if (usage & GRALLOC_USAGE_HW_COMPOSER) { 136ae658e884cc703419ad281d25fa5957db74131ccNaseer Ahmed flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER; 137ae658e884cc703419ad281d25fa5957db74131ccNaseer Ahmed } 138ae658e884cc703419ad281d25fa5957db74131ccNaseer Ahmed 139f2b80d8abab47595b83e3ce9759d4ddccfeafe94Shuzhen Wang if (usage & GRALLOC_USAGE_HW_TEXTURE) { 140f2b80d8abab47595b83e3ce9759d4ddccfeafe94Shuzhen Wang flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE; 141f2b80d8abab47595b83e3ce9759d4ddccfeafe94Shuzhen Wang } 142f2b80d8abab47595b83e3ce9759d4ddccfeafe94Shuzhen Wang 143202a77d28ac251545f6f998a974690212309b927Iliyan Malchev flags |= data.allocType; 144c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan int eBaseAddr = int(eData.base) + eData.offset; 145c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan private_handle_t *hnd = new private_handle_t(data.fd, size, flags, 146c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan bufferType, format, width, height, eData.fd, eData.offset, 147c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan eBaseAddr); 148202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 149202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->offset = data.offset; 150202a77d28ac251545f6f998a974690212309b927Iliyan Malchev hnd->base = int(data.base) + data.offset; 151aee73e2656d1176ee29d20218947fc3a379818b3Naseer Ahmed hnd->gpuaddr = 0; 152aee73e2656d1176ee29d20218947fc3a379818b3Naseer Ahmed 153202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *pHandle = hnd; 154202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 155202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 156202a77d28ac251545f6f998a974690212309b927Iliyan Malchev ALOGE_IF(err, "gralloc failed err=%s", strerror(-err)); 157c0945d8a389f71cdf8432947a6911838d1219c4bRamkumar Radhakrishnan 158202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 159202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 160202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 161202a77d28ac251545f6f998a974690212309b927Iliyan Malchevvoid gpu_context_t::getGrallocInformationFromFormat(int inputFormat, 162202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int *bufferType) 163202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 164202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *bufferType = BUFFER_TYPE_VIDEO; 165202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 166277c3f1bc1ae90749ab5fbbf7225b578bcf4fb79Jesse Hall if (inputFormat <= HAL_PIXEL_FORMAT_sRGB_X_8888) { 167202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // RGB formats 168202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *bufferType = BUFFER_TYPE_UI; 169202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) || 170202a77d28ac251545f6f998a974690212309b927Iliyan Malchev (inputFormat == HAL_PIXEL_FORMAT_RG_88)) { 171202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *bufferType = BUFFER_TYPE_UI; 172202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 173202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 174202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 1755aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmedint gpu_context_t::gralloc_alloc_framebuffer_locked(size_t size, int usage, 1765aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed buffer_handle_t* pHandle) 1775aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed{ 1785aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 1795aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 1805aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // we don't support framebuffer allocations with graphics heap flags 1815aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (usage & GRALLOC_HEAP_MASK) { 1825aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return -EINVAL; 1835aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 1845aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 1855aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (m->framebuffer == NULL) { 1865aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed ALOGE("%s: Invalid framebuffer", __FUNCTION__); 1875aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return -EINVAL; 1885aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 1895aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 1905aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed const uint32_t bufferMask = m->bufferMask; 1915aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed const uint32_t numBuffers = m->numBuffers; 1925aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed size_t bufferSize = m->finfo.line_length * m->info.yres; 1935aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 1945aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed //adreno needs FB size to be page aligned 1955aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed bufferSize = roundUpToPageSize(bufferSize); 1965aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 1975aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (numBuffers == 1) { 1985aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // If we have only one buffer, we never use page-flipping. Instead, 1995aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // we return a regular buffer which will be memcpy'ed to the main 2005aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // screen when post is called. 2015aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; 2025aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI, 2035aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed m->fbFormat, m->info.xres, m->info.yres); 2045aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 2055aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2065aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (bufferMask >= ((1LU<<numBuffers)-1)) { 2075aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // We ran out of buffers. 2085aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return -ENOMEM; 2095aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 2105aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2115aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // create a "fake" handle for it 2125aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed intptr_t vaddr = intptr_t(m->framebuffer->base); 2135aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed private_handle_t* hnd = new private_handle_t( 2145aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed dup(m->framebuffer->fd), bufferSize, 2155aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed private_handle_t::PRIV_FLAGS_USES_PMEM | 2165aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed private_handle_t::PRIV_FLAGS_FRAMEBUFFER, 2175aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed BUFFER_TYPE_UI, m->fbFormat, m->info.xres, 2185aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed m->info.yres); 2195aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2205aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // find a free slot 2215aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed for (uint32_t i=0 ; i<numBuffers ; i++) { 2225aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if ((bufferMask & (1LU<<i)) == 0) { 2235aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed m->bufferMask |= (1LU<<i); 2245aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed break; 2255aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 2265aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed vaddr += bufferSize; 2275aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 2285aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed hnd->base = vaddr; 2295aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed hnd->offset = vaddr - intptr_t(m->framebuffer->base); 2305aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed *pHandle = hnd; 2315aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return 0; 2325aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed} 2335aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2345aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2355aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmedint gpu_context_t::gralloc_alloc_framebuffer(size_t size, int usage, 2365aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed buffer_handle_t* pHandle) 2375aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed{ 2385aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 2395aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed pthread_mutex_lock(&m->lock); 2405aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed int err = gralloc_alloc_framebuffer_locked(size, usage, pHandle); 2415aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed pthread_mutex_unlock(&m->lock); 2425aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return err; 2435aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed} 2445aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 245202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::alloc_impl(int w, int h, int format, int usage, 24629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t* pHandle, int* pStride, 24729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed size_t bufferSize) { 248202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (!pHandle || !pStride) 249202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 250202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 251202a77d28ac251545f6f998a974690212309b927Iliyan Malchev size_t size; 252202a77d28ac251545f6f998a974690212309b927Iliyan Malchev int alignedw, alignedh; 25359802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed int grallocFormat = format; 25459802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed int bufferType; 25559802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed 256aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on 257aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah //the usage bits, gralloc assigns a format. 258277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED || 259277b124c636c4bfc891d2481fe939224b93d788eNaseer Ahmed format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 260aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) 2610bf0358c270b7700f6049da5354a1c0c656fcdedShuzhen Wang grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12 262aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah else if(usage & GRALLOC_USAGE_HW_CAMERA_READ) 263aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21 264aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE) 265aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21 266aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah } 26759802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed 268aedf2368849a863c651fdbb553ffa2eab007a762Saurabh Shah getGrallocInformationFromFormat(grallocFormat, &bufferType); 26959802500bc68ec349bd2ac2e3a01daa94c81a88aNaseer Ahmed size = getBufferSizeAndDimensions(w, h, grallocFormat, alignedw, alignedh); 270202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 271202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if ((ssize_t)size <= 0) 272202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 273255a8efe67a8e2f423ca994abb0470812a67e501Naseer Ahmed size = (bufferSize >= size)? bufferSize : size; 274202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 275202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // All buffers marked as protected or for external 276202a77d28ac251545f6f998a974690212309b927Iliyan Malchev // display need to go to overlay 277202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if ((usage & GRALLOC_USAGE_EXTERNAL_DISP) || 278e94e0aa7e7259138ffe895bcd9daaa5bde9eafa5Sushil Chauhan (usage & GRALLOC_USAGE_PROTECTED)) { 27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed bufferType = BUFFER_TYPE_VIDEO; 280202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 28183e63e60e01a80871a00b9ff52e8987b36622096Naseer Ahmed 2825aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed bool useFbMem = false; 2835aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed char property[PROPERTY_VALUE_MAX]; 2845aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if((usage & GRALLOC_USAGE_HW_FB) && 2855aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed (property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && 2865aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 2875aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 2885aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed useFbMem = true; 2895aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 2905aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 2915aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed int err = 0; 2925aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if(useFbMem) { 2935aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed err = gralloc_alloc_framebuffer(size, usage, pHandle); 2945aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } else { 2955aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed err = gralloc_alloc_buffer(size, usage, pHandle, bufferType, 2965aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed grallocFormat, alignedw, alignedh); 2975aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 298202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 299202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (err < 0) { 300202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return err; 301202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 302202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 303202a77d28ac251545f6f998a974690212309b927Iliyan Malchev *pStride = alignedw; 304202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 305202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 306202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 307202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::free_impl(private_handle_t const* hnd) { 308202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_module_t* m = reinterpret_cast<private_module_t*>(common.module); 3095aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) { 3105aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed const size_t bufferSize = m->finfo.line_length * m->info.yres; 3115aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed int index = (hnd->base - m->framebuffer->base) / bufferSize; 3125aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed m->bufferMask &= ~(1<<index); 3135aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } else { 3145aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed 3155aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd)); 3165aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags); 3175aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed int err = memalloc->free_buffer((void*)hnd->base, (size_t) hnd->size, 3185aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed hnd->offset, hnd->fd); 3195aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if(err) 3205aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return err; 3215aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed // free the metadata space 3225aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t)); 3235aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed err = memalloc->free_buffer((void*)hnd->base_metadata, 3245aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed (size_t) size, hnd->offset_metadata, 3255aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed hnd->fd_metadata); 3265aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed if (err) 3275aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed return err; 3285aa3a5f06ddae46951851fec19ee2e7e20d914cfNaseer Ahmed } 329202a77d28ac251545f6f998a974690212309b927Iliyan Malchev delete hnd; 330202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 331202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 332202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 333202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format, 33429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed int usage, buffer_handle_t* pHandle, 33529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed int* pStride) 336202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 337202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (!dev) { 338202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 339202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 340202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 341202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0); 342202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 34329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedint gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h, 34429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed int format, int usage, 34529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t* pHandle, int* pStride, 34629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed int bufferSize) 347202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 348202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (!dev) { 349202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 350202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 351202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 352202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize); 353202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 354202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 355202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 356202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::gralloc_free(alloc_device_t* dev, 35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed buffer_handle_t handle) 358202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 359202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (private_handle_t::validate(handle) < 0) 360202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return -EINVAL; 361202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 362202a77d28ac251545f6f998a974690212309b927Iliyan Malchev private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); 363202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev); 364202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return gpu->free_impl(hnd); 365202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 366202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 367202a77d28ac251545f6f998a974690212309b927Iliyan Malchev/*****************************************************************************/ 368202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 369202a77d28ac251545f6f998a974690212309b927Iliyan Malchevint gpu_context_t::gralloc_close(struct hw_device_t *dev) 370202a77d28ac251545f6f998a974690212309b927Iliyan Malchev{ 371202a77d28ac251545f6f998a974690212309b927Iliyan Malchev gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev); 372202a77d28ac251545f6f998a974690212309b927Iliyan Malchev if (ctx) { 373202a77d28ac251545f6f998a974690212309b927Iliyan Malchev /* TODO: keep a list of all buffer_handle_t created, and free them 374202a77d28ac251545f6f998a974690212309b927Iliyan Malchev * all here. 375202a77d28ac251545f6f998a974690212309b927Iliyan Malchev */ 376202a77d28ac251545f6f998a974690212309b927Iliyan Malchev delete ctx; 377202a77d28ac251545f6f998a974690212309b927Iliyan Malchev } 378202a77d28ac251545f6f998a974690212309b927Iliyan Malchev return 0; 379202a77d28ac251545f6f998a974690212309b927Iliyan Malchev} 380202a77d28ac251545f6f998a974690212309b927Iliyan Malchev 381