upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1,49 @@
# Copyright (C) 2008 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Gralloc module
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/../common.mk
include $(CLEAR_VARS)
LOCAL_MODULE := gralloc.$(TARGET_BOARD_PLATFORM)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libmemalloc libqdMetaData
LOCAL_SHARED_LIBRARIES += libqdutils libGLESv1_CM
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdgralloc\"
LOCAL_CLANG := $(common_clang_flags)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := gpu.cpp gralloc.cpp framebuffer.cpp mapper.cpp
LOCAL_COPY_HEADERS_TO := $(common_header_export_path)
LOCAL_COPY_HEADERS := gralloc_priv.h gr.h
include $(BUILD_SHARED_LIBRARY)
# MemAlloc Library
include $(CLEAR_VARS)
LOCAL_MODULE := libmemalloc
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
LOCAL_SHARED_LIBRARIES := $(common_libs) libqdutils libdl
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdmemalloc\"
LOCAL_CLANG := $(common_clang_flags)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
LOCAL_SRC_FILES := ionalloc.cpp alloc_controller.cpp
LOCAL_COPY_HEADERS := alloc_controller.h memalloc.h
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,190 @@
Copyright (c) 2008-2009, The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View file

@ -0,0 +1,675 @@
/*
* Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <cutils/log.h>
#include <fcntl.h>
#include <dlfcn.h>
#include "gralloc_priv.h"
#include "alloc_controller.h"
#include "memalloc.h"
#include "ionalloc.h"
#include "gr.h"
#include "comptype.h"
#include "mdp_version.h"
#ifdef VENUS_COLOR_FORMAT
#include <media/msm_media_info.h>
#else
#define VENUS_Y_STRIDE(args...) 0
#define VENUS_Y_SCANLINES(args...) 0
#define VENUS_BUFFER_SIZE(args...) 0
#endif
#define ASTC_BLOCK_SIZE 16
using namespace gralloc;
using namespace qdutils;
ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
//Common functions
static bool canFallback(int usage, bool triedSystem)
{
// Fallback to system heap when alloc fails unless
// 1. Composition type is MDP
// 2. Alloc from system heap was already tried
// 3. The heap type is requsted explicitly
// 4. The heap type is protected
// 5. The buffer is meant for external display only
if(QCCompositionType::getInstance().getCompositionType() &
COMPOSITION_TYPE_MDP)
return false;
if(triedSystem)
return false;
if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
return false;
if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
return false;
//Return true by default
return true;
}
/* The default policy is to return cached buffers unless the client explicity
* sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
* read or written in software. Any combination with a _RARELY_ flag will be
* treated as uncached. */
static bool useUncached(const int& usage) {
if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
GRALLOC_USAGE_SW_WRITE_RARELY) or
((usage & GRALLOC_USAGE_SW_READ_MASK) ==
GRALLOC_USAGE_SW_READ_RARELY))
return true;
return false;
}
//-------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo()
{
LINK_adreno_compute_aligned_width_and_height = NULL;
LINK_adreno_compute_padding = NULL;
LINK_adreno_isMacroTilingSupportedByGpu = NULL;
LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
LINK_adreno_get_gpu_pixel_alignment = NULL;
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils) {
*(void **)&LINK_adreno_compute_aligned_width_and_height =
::dlsym(libadreno_utils, "compute_aligned_width_and_height");
*(void **)&LINK_adreno_compute_padding =
::dlsym(libadreno_utils, "compute_surface_padding");
*(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
*(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
::dlsym(libadreno_utils,
"compute_compressedfmt_aligned_width_and_height");
*(void **)&LINK_adreno_get_gpu_pixel_alignment =
::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
}
}
AdrenoMemInfo::~AdrenoMemInfo()
{
if (libadreno_utils) {
::dlclose(libadreno_utils);
}
}
int AdrenoMemInfo::isMacroTilingSupportedByGPU()
{
if ((libadreno_utils)) {
if(LINK_adreno_isMacroTilingSupportedByGpu) {
return LINK_adreno_isMacroTilingSupportedByGpu();
}
}
return 0;
}
void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
int tile_enabled, int& aligned_w, int& aligned_h)
{
aligned_w = width;
aligned_h = height;
// Currently surface padding is only computed for RGB* surfaces.
if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
aligned_w = ALIGN(width, 32);
aligned_h = ALIGN(height, 32);
int bpp = 4;
switch(format)
{
case HAL_PIXEL_FORMAT_RGBA_FP16:
bpp = 8;
break;
case HAL_PIXEL_FORMAT_RGB_888:
bpp = 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
bpp = 2;
break;
default: break;
}
if (libadreno_utils) {
int raster_mode = 0; // Adreno unknown raster mode.
int padding_threshold = 512; // Threshold for padding surfaces.
// the function below computes aligned width and aligned height
// based on linear or macro tile mode selected.
if(LINK_adreno_compute_aligned_width_and_height) {
LINK_adreno_compute_aligned_width_and_height(width,
height, bpp, tile_enabled,
raster_mode, padding_threshold,
&aligned_w, &aligned_h);
} else if(LINK_adreno_compute_padding) {
int surface_tile_height = 1; // Linear surface
aligned_w = LINK_adreno_compute_padding(width, bpp,
surface_tile_height, raster_mode,
padding_threshold);
ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
__FUNCTION__);
} else {
ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
"compute_aligned_width_and_height not found", __FUNCTION__);
}
}
} else {
int alignment = 32;
switch (format)
{
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
if (LINK_adreno_get_gpu_pixel_alignment) {
alignment = LINK_adreno_get_gpu_pixel_alignment();
}
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
aligned_w = ALIGN(width, alignment);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
aligned_w = ALIGN(width, 128);
break;
case HAL_PIXEL_FORMAT_YV12:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
aligned_w = ALIGN(width, 16);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
break;
case HAL_PIXEL_FORMAT_BLOB:
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
aligned_w = ALIGN(width, 64);
aligned_h = ALIGN(height, 64);
break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
int bytesPerPixel = 0;
int raster_mode = 0; //Adreno unknown raster mode.
int padding_threshold = 512; //Threshold for padding
//surfaces.
LINK_adreno_compute_compressedfmt_aligned_width_and_height(
width, height, format, 0,raster_mode, padding_threshold,
&aligned_w, &aligned_h, &bytesPerPixel);
} else {
ALOGW("%s: Warning!! Symbols" \
" compute_compressedfmt_aligned_width_and_height" \
" not found", __FUNCTION__);
}
break;
default: break;
}
}
}
//-------------- IAllocController-----------------------//
IAllocController* IAllocController::sController = NULL;
IAllocController* IAllocController::getInstance(void)
{
if(sController == NULL) {
sController = new IonController();
}
return sController;
}
//-------------- IonController-----------------------//
IonController::IonController()
{
allocateIonMem();
}
void IonController::allocateIonMem()
{
mIonAlloc = new IonAlloc();
}
int IonController::allocate(alloc_data& data, int usage)
{
int ionFlags = 0;
int ret;
data.uncached = useUncached(usage);
data.allocType = 0;
if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
if(usage & GRALLOC_USAGE_PROTECTED) {
if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
ionFlags |= ION_SECURE;
} else {
// for targets/OEMs which do not need HW level protection
// do not set ion secure flag & MM heap. Fallback to IOMMU heap.
ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
}
} else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
//MM Heap is exclusively a secure heap.
//If it is used for non secure cases, fallback to IOMMU heap
ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
cannot be used as an insecure heap!\
trying to use IOMMU instead !!");
ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
}
if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
if(ionFlags & ION_SECURE)
data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
// if no flags are set, default to
// SF + IOMMU heaps, so that bypass can work
// we can fall back to system heap if
// we run out.
if(!ionFlags)
ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
data.flags = ionFlags;
ret = mIonAlloc->alloc_buffer(data);
// Fallback
if(ret < 0 && canFallback(usage,
(ionFlags & ION_SYSTEM_HEAP_ID)))
{
ALOGW("Falling back to system heap");
data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
ret = mIonAlloc->alloc_buffer(data);
}
if(ret >= 0 ) {
data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
}
return ret;
}
IMemAlloc* IonController::getAllocator(int flags)
{
IMemAlloc* memalloc = NULL;
if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
memalloc = mIonAlloc;
} else {
ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
}
return memalloc;
}
bool isMacroTileEnabled(int format, int usage)
{
bool tileEnabled = false;
// Check whether GPU & MDSS supports MacroTiling feature
if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
qdutils::MDPVersion::getInstance().supportsMacroTile())
{
// check the format
switch(format)
{
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGB_565:
{
tileEnabled = true;
// check the usage flags
if (usage & (GRALLOC_USAGE_SW_READ_MASK |
GRALLOC_USAGE_SW_WRITE_MASK)) {
// Application intends to use CPU for rendering
tileEnabled = false;
}
break;
}
default:
break;
}
}
return tileEnabled;
}
// helper function
unsigned int getSize(int format, int width, int height, const int alignedw,
const int alignedh) {
unsigned int size = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_FP16:
size = alignedw * alignedh * 8;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
case HAL_PIXEL_FORMAT_RGBA_1010102:
size = alignedw * alignedh * 4;
break;
case HAL_PIXEL_FORMAT_RGB_888:
size = alignedw * alignedh * 3;
break;
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_RAW16:
size = alignedw * alignedh * 2;
break;
// adreno formats
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
size = ALIGN(alignedw*alignedh, 4096);
size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
// The chroma plane is subsampled,
// but the pitch in bytes is unchanged
// The GPU needs 4K alignment, but the video decoder needs 8K
size = ALIGN( alignedw * alignedh, 8192);
size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
break;
case HAL_PIXEL_FORMAT_YV12:
if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
ALOGE("w or h is odd for the YV12 format");
return 0;
}
size = alignedw*alignedh +
(ALIGN(alignedw/2, 16) * (alignedh/2))*2;
size = ALIGN(size, (unsigned int)4096);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
if(width & 1) {
ALOGE("width is odd for the YUV422_SP format");
return 0;
}
size = ALIGN(alignedw * alignedh * 2, 4096);
break;
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
break;
case HAL_PIXEL_FORMAT_BLOB:
if(height != 1) {
ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
must have height==1 ", __FUNCTION__);
return 0;
}
size = width;
break;
case HAL_PIXEL_FORMAT_NV21_ZSL:
size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
break;
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
size = alignedw * alignedh * ASTC_BLOCK_SIZE;
break;
default:
ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
return 0;
}
return size;
}
unsigned int getBufferSizeAndDimensions(int width, int height, int format,
int& alignedw, int &alignedh)
{
unsigned int size;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
false,
alignedw,
alignedh);
size = getSize(format, width, height, alignedw, alignedh);
return size;
}
unsigned int getBufferSizeAndDimensions(int width, int height, int format,
int usage, int& alignedw, int &alignedh)
{
unsigned int size;
int tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
tileEnabled,
alignedw,
alignedh);
size = getSize(format, width, height, alignedw, alignedh);
return size;
}
void getBufferAttributes(int width, int height, int format, int usage,
int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
{
tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
tileEnabled,
alignedw,
alignedh);
size = getSize(format, width, height, alignedw, alignedh);
}
int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
{
int err = 0;
unsigned int ystride, cstride;
memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
// Get the chroma offsets from the handle width/height. We take advantage
// of the fact the width _is_ the stride
switch (hnd->format) {
//Semiplanar
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
ystride = cstride = hnd->width;
ycbcr->y = (void*)hnd->base;
ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 2;
break;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCrCb_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
case HAL_PIXEL_FORMAT_NV21_ZSL:
ystride = cstride = hnd->width;
ycbcr->y = (void*)hnd->base;
ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 2;
break;
//Planar
case HAL_PIXEL_FORMAT_YV12:
ystride = hnd->width;
cstride = ALIGN(hnd->width/2, 16);
ycbcr->y = (void*)hnd->base;
ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
cstride * hnd->height/2);
ycbcr->ystride = ystride;
ycbcr->cstride = cstride;
ycbcr->chroma_step = 1;
break;
//Unsupported formats
case HAL_PIXEL_FORMAT_YCbCr_422_I:
case HAL_PIXEL_FORMAT_YCrCb_422_I:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
default:
ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
hnd->format);
err = -EINVAL;
}
return err;
}
// Allocate buffer from width, height and format into a
// private_handle_t. It is the responsibility of the caller
// to free the buffer using the free_buffer function
int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
{
alloc_data data;
int alignedw, alignedh;
gralloc::IAllocController* sAlloc =
gralloc::IAllocController::getInstance();
data.base = 0;
data.fd = -1;
data.offset = 0;
data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
alignedh);
data.align = getpagesize();
data.uncached = useUncached(usage);
int allocFlags = usage;
int err = sAlloc->allocate(data, allocFlags);
if (0 != err) {
ALOGE("%s: allocate failed", __FUNCTION__);
return -ENOMEM;
}
private_handle_t* hnd = new private_handle_t(data.fd, data.size,
data.allocType, 0, format,
alignedw, alignedh);
hnd->base = (uint64_t) data.base;
hnd->offset = data.offset;
hnd->gpuaddr = 0;
*pHnd = hnd;
return 0;
}
void free_buffer(private_handle_t *hnd)
{
gralloc::IAllocController* sAlloc =
gralloc::IAllocController::getInstance();
if (hnd && hnd->fd > 0) {
IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
}
if(hnd)
delete hnd;
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRALLOC_ALLOCCONTROLLER_H
#define GRALLOC_ALLOCCONTROLLER_H
namespace gralloc {
struct alloc_data;
class IMemAlloc;
class IonAlloc;
class IAllocController {
public:
/* Allocate using a suitable method
* Returns the type of buffer allocated
*/
virtual int allocate(alloc_data& data, int usage) = 0;
virtual IMemAlloc* getAllocator(int flags) = 0;
virtual ~IAllocController() {};
static IAllocController* getInstance(void);
private:
static IAllocController* sController;
};
class IonController : public IAllocController {
public:
virtual int allocate(alloc_data& data, int usage);
virtual IMemAlloc* getAllocator(int flags);
IonController();
private:
IonAlloc* mIonAlloc;
void allocateIonMem();
};
} //end namespace gralloc
#endif // GRALLOC_ALLOCCONTROLLER_H

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FB_PRIV_H
#define FB_PRIV_H
#include <linux/fb.h>
#include <linux/msm_mdp.h>
#define NUM_FRAMEBUFFERS_MIN 2
#define NUM_FRAMEBUFFERS_MAX 3
#define NO_SURFACEFLINGER_SWAPINTERVAL
#define COLOR_FORMAT(x) (x & 0xFFF) // Max range for colorFormats is 0 - FFF
struct private_handle_t;
enum {
// flag to indicate we'll post this buffer
PRIV_USAGE_LOCKED_FOR_POST = 0x80000000,
PRIV_MIN_SWAP_INTERVAL = 0,
PRIV_MAX_SWAP_INTERVAL = 1,
};
struct private_module_t {
gralloc_module_t base;
struct private_handle_t* framebuffer;
uint32_t fbFormat;
uint32_t flags;
uint32_t numBuffers;
uint32_t bufferMask;
pthread_mutex_t lock;
struct fb_var_screeninfo info;
struct fb_fix_screeninfo finfo;
float xdpi;
float ydpi;
float fps;
uint32_t swapInterval;
};
#endif /* FB_PRIV_H */

View file

@ -0,0 +1,455 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2014,2016 The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <sys/mman.h>
#include <cutils/log.h>
#include <cutils/properties.h>
#include <dlfcn.h>
#include <hardware/hardware.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <cutils/atomic.h>
#include <linux/fb.h>
#include <linux/msm_mdp.h>
#include <GLES/gl.h>
#include "gralloc_priv.h"
#include "fb_priv.h"
#include "gr.h"
#include <cutils/properties.h>
#include <profiler.h>
#define EVEN_OUT(x) if (x & 0x0001) {x--;}
enum {
PAGE_FLIP = 0x00000001,
};
struct fb_context_t {
framebuffer_device_t device;
//fd - which is returned on open
int fbFd;
};
static int fb_setSwapInterval(struct framebuffer_device_t* dev,
int interval)
{
#ifdef DEBUG_SWAPINTERVAL
//XXX: Get the value here and implement along with
//single vsync in HWC
char pval[PROPERTY_VALUE_MAX];
property_get("debug.egl.swapinterval", pval, "-1");
int property_interval = atoi(pval);
if (property_interval >= 0)
interval = property_interval;
#endif
private_module_t* m = reinterpret_cast<private_module_t*>(
dev->common.module);
if (interval < dev->minSwapInterval || interval > dev->maxSwapInterval)
return -EINVAL;
m->swapInterval = interval;
return 0;
}
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
{
private_module_t* m =
reinterpret_cast<private_module_t*>(dev->common.module);
private_handle_t *hnd = static_cast<private_handle_t*>
(const_cast<native_handle_t*>(buffer));
fb_context_t *ctx = reinterpret_cast<fb_context_t*>(dev);
const unsigned int offset = (unsigned int) (hnd->base -
m->framebuffer->base);
m->info.activate = FB_ACTIVATE_VBL;
m->info.yoffset = (int)(offset / m->finfo.line_length);
if (ioctl(ctx->fbFd, FBIOPUT_VSCREENINFO, &m->info) == -1) {
ALOGE("%s: FBIOPUT_VSCREENINFO for primary failed, str: %s",
__FUNCTION__, strerror(errno));
return -errno;
}
return 0;
}
static int fb_compositionComplete(struct framebuffer_device_t* dev)
{
// TODO: Properly implement composition complete callback
if(!dev) {
return -1;
}
glFinish();
return 0;
}
int mapFrameBufferLocked(framebuffer_device_t *dev)
{
private_module_t* module =
reinterpret_cast<private_module_t*>(dev->common.module);
fb_context_t *ctx = reinterpret_cast<fb_context_t*>(dev);
// already initialized...
if (module->framebuffer) {
return 0;
}
char const * const device_template[] = {
"/dev/graphics/fb%u",
"/dev/fb%u",
0 };
int fd = -1;
int i=0;
char name[64];
char property[PROPERTY_VALUE_MAX];
while ((fd==-1) && device_template[i]) {
snprintf(name, 64, device_template[i], 0);
fd = open(name, O_RDWR, 0);
i++;
}
if (fd < 0)
return -errno;
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
close(fd);
return -errno;
}
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
close(fd);
return -errno;
}
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
info.xoffset = 0;
info.yoffset = 0;
info.activate = FB_ACTIVATE_NOW;
/* Interpretation of offset for color fields: All offsets are from the
* right, inside a "pixel" value, which is exactly 'bits_per_pixel' wide
* (means: you can use the offset as right argument to <<). A pixel
* afterwards is a bit stream and is written to video memory as that
* unmodified. This implies big-endian byte order if bits_per_pixel is
* greater than 8.
*/
if(info.bits_per_pixel == 32) {
/*
* Explicitly request RGBA_8888
*/
info.bits_per_pixel = 32;
info.red.offset = 24;
info.red.length = 8;
info.green.offset = 16;
info.green.length = 8;
info.blue.offset = 8;
info.blue.length = 8;
info.transp.offset = 0;
info.transp.length = 8;
/* Note: the GL driver does not have a r=8 g=8 b=8 a=0 config, so if we
* do not use the MDP for composition (i.e. hw composition == 0), ask
* for RGBA instead of RGBX. */
if (property_get("debug.sf.hw", property, NULL) > 0 &&
atoi(property) == 0)
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
else if(property_get("debug.composition.type", property, NULL) > 0 &&
(strncmp(property, "mdp", 3) == 0))
module->fbFormat = HAL_PIXEL_FORMAT_RGBX_8888;
else
module->fbFormat = HAL_PIXEL_FORMAT_RGBA_8888;
} else {
/*
* Explicitly request 5/6/5
*/
info.bits_per_pixel = 16;
info.red.offset = 11;
info.red.length = 5;
info.green.offset = 5;
info.green.length = 6;
info.blue.offset = 0;
info.blue.length = 5;
info.transp.offset = 0;
info.transp.length = 0;
module->fbFormat = HAL_PIXEL_FORMAT_RGB_565;
}
//adreno needs 4k aligned offsets. Max hole size is 4096-1
unsigned int size = roundUpToPageSize(info.yres * info.xres *
(info.bits_per_pixel/8));
/*
* Request NUM_BUFFERS screens (at least 2 for page flipping)
*/
int numberOfBuffers = (int)(finfo.smem_len/size);
ALOGV("num supported framebuffers in kernel = %d", numberOfBuffers);
if (property_get("debug.gr.numframebuffers", property, NULL) > 0) {
int num = atoi(property);
if ((num >= NUM_FRAMEBUFFERS_MIN) && (num <= NUM_FRAMEBUFFERS_MAX)) {
numberOfBuffers = num;
}
}
if (numberOfBuffers > NUM_FRAMEBUFFERS_MAX)
numberOfBuffers = NUM_FRAMEBUFFERS_MAX;
ALOGV("We support %d buffers", numberOfBuffers);
//consider the included hole by 4k alignment
uint32_t line_length = (info.xres * info.bits_per_pixel / 8);
info.yres_virtual = (uint32_t) ((size * numberOfBuffers) / line_length);
uint32_t flags = PAGE_FLIP;
if (info.yres_virtual < ((size * 2) / line_length) ) {
// we need at least 2 for page-flipping
info.yres_virtual = (int)(size / line_length);
flags &= ~PAGE_FLIP;
ALOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
info.yres_virtual, info.yres*2);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
close(fd);
return -errno;
}
if (int(info.width) <= 0 || int(info.height) <= 0) {
// the driver doesn't return that information
// default to 160 dpi
info.width = (uint32_t)(((float)(info.xres) * 25.4f)/160.0f + 0.5f);
info.height = (uint32_t)(((float)(info.yres) * 25.4f)/160.0f + 0.5f);
}
float xdpi = ((float)(info.xres) * 25.4f) / (float)info.width;
float ydpi = ((float)(info.yres) * 25.4f) / (float)info.height;
#ifdef MSMFB_METADATA_GET
struct msmfb_metadata metadata;
memset(&metadata, 0 , sizeof(metadata));
metadata.op = metadata_op_frame_rate;
if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
ALOGE("Error retrieving panel frame rate");
close(fd);
return -errno;
}
float fps = (float)metadata.data.panel_frame_rate;
#else
//XXX: Remove reserved field usage on all baselines
//The reserved[3] field is used to store FPS by the driver.
float fps = info.reserved[3] & 0xFF;
#endif
ALOGI("using (fd=%d)\n"
"id = %s\n"
"xres = %d px\n"
"yres = %d px\n"
"xres_virtual = %d px\n"
"yres_virtual = %d px\n"
"bpp = %d\n"
"r = %2u:%u\n"
"g = %2u:%u\n"
"b = %2u:%u\n",
fd,
finfo.id,
info.xres,
info.yres,
info.xres_virtual,
info.yres_virtual,
info.bits_per_pixel,
info.red.offset, info.red.length,
info.green.offset, info.green.length,
info.blue.offset, info.blue.length
);
ALOGI("width = %d mm (%f dpi)\n"
"height = %d mm (%f dpi)\n"
"refresh rate = %.2f Hz\n",
info.width, xdpi,
info.height, ydpi,
fps
);
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
close(fd);
return -errno;
}
if (finfo.smem_len <= 0) {
close(fd);
return -errno;
}
module->flags = flags;
module->info = info;
module->finfo = finfo;
module->xdpi = xdpi;
module->ydpi = ydpi;
module->fps = fps;
module->swapInterval = 1;
CALC_INIT();
/*
* map the framebuffer
*/
module->numBuffers = info.yres_virtual / info.yres;
module->bufferMask = 0;
//adreno needs page aligned offsets. Align the fbsize to pagesize.
unsigned int fbSize = roundUpToPageSize(finfo.line_length * info.yres)*
module->numBuffers;
void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (vaddr == MAP_FAILED) {
ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
close(fd);
return -errno;
}
//store the framebuffer fd in the ctx
ctx->fbFd = fd;
#ifdef MSMFB_METADATA_GET
memset(&metadata, 0 , sizeof(metadata));
metadata.op = metadata_op_get_ion_fd;
// get the ION fd for the framebuffer, as GPU needs ION fd
if (ioctl(fd, MSMFB_METADATA_GET, &metadata) == -1) {
ALOGE("Error getting ION fd (%s)", strerror(errno));
close(fd);
return -errno;
}
if(metadata.data.fbmem_ionfd < 0) {
ALOGE("Error: Ioctl returned invalid ION fd = %d",
metadata.data.fbmem_ionfd);
close(fd);
return -errno;
}
fd = metadata.data.fbmem_ionfd;
#endif
// Create framebuffer handle using the ION fd
module->framebuffer = new private_handle_t(fd, fbSize,
private_handle_t::PRIV_FLAGS_USES_ION,
BUFFER_TYPE_UI,
module->fbFormat, info.xres, info.yres);
module->framebuffer->base = uint64_t(vaddr);
memset(vaddr, 0, fbSize);
//Enable vsync
int enable = 1;
ioctl(ctx->fbFd, MSMFB_OVERLAY_VSYNC_CTRL, &enable);
return 0;
}
static int mapFrameBuffer(framebuffer_device_t *dev)
{
int err = -1;
char property[PROPERTY_VALUE_MAX];
if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
(!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
(!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
private_module_t* module =
reinterpret_cast<private_module_t*>(dev->common.module);
pthread_mutex_lock(&module->lock);
err = mapFrameBufferLocked(dev);
pthread_mutex_unlock(&module->lock);
}
return err;
}
/*****************************************************************************/
static int fb_close(struct hw_device_t *dev)
{
fb_context_t* ctx = (fb_context_t*)dev;
if (ctx) {
#ifdef MSMFB_METADATA_GET
if(ctx->fbFd >=0) {
close(ctx->fbFd);
}
#endif
//Hack until fbdev is removed. Framework could close this causing hwc a
//pain.
//free(ctx);
}
return 0;
}
int fb_device_open(hw_module_t const* module, const char* name,
hw_device_t** device)
{
int status = -EINVAL;
if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
alloc_device_t* gralloc_device;
status = gralloc_open(module, &gralloc_device);
if (status < 0)
return status;
/* initialize our state here */
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
if(dev == NULL) {
gralloc_close(gralloc_device);
return status;
}
memset(dev, 0, sizeof(*dev));
/* initialize the procs */
dev->device.common.tag = HARDWARE_DEVICE_TAG;
dev->device.common.version = 0;
dev->device.common.module = const_cast<hw_module_t*>(module);
dev->device.common.close = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post = fb_post;
dev->device.setUpdateRect = 0;
dev->device.compositionComplete = fb_compositionComplete;
status = mapFrameBuffer((framebuffer_device_t*)dev);
private_module_t* m = (private_module_t*)dev->device.common.module;
if (status >= 0) {
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
const_cast<uint32_t&>(dev->device.flags) = 0;
const_cast<uint32_t&>(dev->device.width) = m->info.xres;
const_cast<uint32_t&>(dev->device.height) = m->info.yres;
const_cast<int&>(dev->device.stride) = stride;
const_cast<int&>(dev->device.format) = m->fbFormat;
const_cast<float&>(dev->device.xdpi) = m->xdpi;
const_cast<float&>(dev->device.ydpi) = m->ydpi;
const_cast<float&>(dev->device.fps) = m->fps;
const_cast<int&>(dev->device.minSwapInterval) =
PRIV_MIN_SWAP_INTERVAL;
const_cast<int&>(dev->device.maxSwapInterval) =
PRIV_MAX_SWAP_INTERVAL;
const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
dev->device.setUpdateRect = 0;
*device = &dev->device.common;
}
// Close the gralloc module
gralloc_close(gralloc_device);
}
return status;
}

View file

@ -0,0 +1,402 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (c) 2011-2014 The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <cutils/properties.h>
#include <sys/mman.h>
#include "gr.h"
#include "gpu.h"
#include "memalloc.h"
#include "alloc_controller.h"
#include <qdMetaData.h>
using namespace gralloc;
#define SZ_1M 0x100000
gpu_context_t::gpu_context_t(const private_module_t* module,
IAllocController* alloc_ctrl ) :
mAllocCtrl(alloc_ctrl)
{
// Zero out the alloc_device_t
memset(static_cast<alloc_device_t*>(this), 0, sizeof(alloc_device_t));
// Initialize the procs
common.tag = HARDWARE_DEVICE_TAG;
common.version = 0;
common.module = const_cast<hw_module_t*>(&module->base.common);
common.close = gralloc_close;
alloc = gralloc_alloc;
free = gralloc_free;
}
int gpu_context_t::gralloc_alloc_buffer(unsigned int size, int usage,
buffer_handle_t* pHandle, int bufferType,
int format, int width, int height)
{
int err = 0;
int flags = 0;
size = roundUpToPageSize(size);
alloc_data data;
data.offset = 0;
data.fd = -1;
data.base = 0;
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED)
data.align = 8192;
else
data.align = getpagesize();
/* force 1MB alignment selectively for secure buffers, MDP5 onwards */
#ifdef MDSS_TARGET
if ((usage & GRALLOC_USAGE_PROTECTED) &&
(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)) {
data.align = ALIGN((int) data.align, SZ_1M);
size = ALIGN(size, data.align);
}
#endif
data.size = size;
data.pHandle = (uintptr_t) pHandle;
err = mAllocCtrl->allocate(data, usage);
if (!err) {
/* allocate memory for enhancement data */
alloc_data eData;
eData.fd = -1;
eData.base = 0;
eData.offset = 0;
eData.size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
eData.pHandle = data.pHandle;
eData.align = getpagesize();
int eDataUsage = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
int eDataErr = mAllocCtrl->allocate(eData, eDataUsage);
ALOGE_IF(eDataErr, "gralloc failed for eDataErr=%s",
strerror(-eDataErr));
if (usage & GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY) {
flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
}
if (usage & GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY) {
flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
}
ColorSpace_t colorSpace = ITU_R_601;
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
if (bufferType == BUFFER_TYPE_VIDEO) {
if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
#ifndef MDSS_TARGET
colorSpace = ITU_R_601_FR;
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
#else
// Per the camera spec ITU 709 format should be set only for
// video encoding.
// It should be set to ITU 601 full range format for any other
// camera buffer
//
if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
colorSpace = ITU_R_709;
} else {
flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
colorSpace = ITU_R_601_FR;
}
}
#endif
}
}
if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER ) {
flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
}
if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
}
if (usage & GRALLOC_USAGE_HW_CAMERA_READ) {
flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
}
if (usage & GRALLOC_USAGE_HW_COMPOSER) {
flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
}
if (usage & GRALLOC_USAGE_HW_TEXTURE) {
flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
}
if(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
if(isMacroTileEnabled(format, usage)) {
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}
if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
}
if (usage & (GRALLOC_USAGE_HW_VIDEO_ENCODER |
GRALLOC_USAGE_HW_CAMERA_WRITE |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_FB)) {
flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
}
if(false == data.uncached) {
flags |= private_handle_t::PRIV_FLAGS_CACHED;
}
flags |= data.allocType;
uint64_t eBaseAddr = (uint64_t)(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
bufferType, format, width, height, eData.fd, eData.offset,
eBaseAddr);
hnd->offset = data.offset;
hnd->base = (uint64_t)(data.base) + data.offset;
hnd->gpuaddr = 0;
setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
*pHandle = hnd;
}
ALOGE_IF(err, "gralloc failed err=%s", strerror(-err));
return err;
}
void gpu_context_t::getGrallocInformationFromFormat(int inputFormat,
int *bufferType)
{
*bufferType = BUFFER_TYPE_VIDEO;
if (inputFormat <= HAL_PIXEL_FORMAT_BGRA_8888) {
// RGB formats
*bufferType = BUFFER_TYPE_UI;
} else if ((inputFormat == HAL_PIXEL_FORMAT_R_8) ||
(inputFormat == HAL_PIXEL_FORMAT_RG_88)) {
*bufferType = BUFFER_TYPE_UI;
}
}
int gpu_context_t::gralloc_alloc_framebuffer_locked(int usage,
buffer_handle_t* pHandle)
{
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
// we don't support framebuffer allocations with graphics heap flags
if (usage & GRALLOC_HEAP_MASK) {
return -EINVAL;
}
if (m->framebuffer == NULL) {
ALOGE("%s: Invalid framebuffer", __FUNCTION__);
return -EINVAL;
}
const unsigned int bufferMask = m->bufferMask;
const uint32_t numBuffers = m->numBuffers;
unsigned int bufferSize = m->finfo.line_length * m->info.yres;
//adreno needs FB size to be page aligned
bufferSize = roundUpToPageSize(bufferSize);
if (numBuffers == 1) {
// If we have only one buffer, we never use page-flipping. Instead,
// we return a regular buffer which will be memcpy'ed to the main
// screen when post is called.
int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D;
return gralloc_alloc_buffer(bufferSize, newUsage, pHandle, BUFFER_TYPE_UI,
m->fbFormat, m->info.xres, m->info.yres);
}
if (bufferMask >= ((1LU<<numBuffers)-1)) {
// We ran out of buffers.
return -ENOMEM;
}
// create a "fake" handle for it
uint64_t vaddr = uint64_t(m->framebuffer->base);
// As GPU needs ION FD, the private handle is created
// using ION fd and ION flags are set
private_handle_t* hnd = new private_handle_t(
dup(m->framebuffer->fd), bufferSize,
private_handle_t::PRIV_FLAGS_USES_ION |
private_handle_t::PRIV_FLAGS_FRAMEBUFFER,
BUFFER_TYPE_UI, m->fbFormat, m->info.xres,
m->info.yres);
// find a free slot
for (uint32_t i=0 ; i<numBuffers ; i++) {
if ((bufferMask & (1LU<<i)) == 0) {
m->bufferMask |= (uint32_t)(1LU<<i);
break;
}
vaddr += bufferSize;
}
hnd->base = vaddr;
hnd->offset = (unsigned int)(vaddr - m->framebuffer->base);
*pHandle = hnd;
return 0;
}
int gpu_context_t::gralloc_alloc_framebuffer(int usage,
buffer_handle_t* pHandle)
{
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
pthread_mutex_lock(&m->lock);
int err = gralloc_alloc_framebuffer_locked(usage, pHandle);
pthread_mutex_unlock(&m->lock);
return err;
}
int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride,
unsigned int bufferSize) {
if (!pHandle || !pStride)
return -EINVAL;
unsigned int size;
int alignedw, alignedh;
int grallocFormat = format;
int bufferType;
//If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
//the usage bits, gralloc assigns a format.
if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
== GRALLOC_USAGE_HW_CAMERA_ZSL)
grallocFormat = HAL_PIXEL_FORMAT_NV21_ZSL; //NV21 ZSL
else if(usage & GRALLOC_USAGE_HW_CAMERA_READ)
grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
else if(usage & GRALLOC_USAGE_HW_CAMERA_WRITE)
grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP; //NV21
else if(usage & GRALLOC_USAGE_HW_COMPOSER)
//XXX: If we still haven't set a format, default to RGBA8888
grallocFormat = HAL_PIXEL_FORMAT_RGBA_8888;
//If no other usage flags are detected, default the
//flexible YUV format to NV21.
else if(format == HAL_PIXEL_FORMAT_YCbCr_420_888)
grallocFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
}
getGrallocInformationFromFormat(grallocFormat, &bufferType);
size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
alignedh);
if ((unsigned int)size <= 0)
return -EINVAL;
size = (bufferSize >= size)? bufferSize : size;
int err = 0;
err = gralloc_alloc_buffer(size, usage, pHandle, bufferType,
grallocFormat, alignedw, alignedh);
if (err < 0) {
return err;
}
*pStride = alignedw;
return 0;
}
int gpu_context_t::free_impl(private_handle_t const* hnd) {
private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
const unsigned int bufferSize = m->finfo.line_length * m->info.yres;
unsigned int index = (unsigned int) ((hnd->base - m->framebuffer->base)
/ bufferSize);
m->bufferMask &= (uint32_t)~(1LU<<index);
} else {
terminateBuffer(&m->base, const_cast<private_handle_t*>(hnd));
IMemAlloc* memalloc = mAllocCtrl->getAllocator(hnd->flags);
int err = memalloc->free_buffer((void*)hnd->base, hnd->size,
hnd->offset, hnd->fd);
if(err)
return err;
// free the metadata space
unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
err = memalloc->free_buffer((void*)hnd->base_metadata,
size, hnd->offset_metadata,
hnd->fd_metadata);
if (err)
return err;
}
delete hnd;
return 0;
}
int gpu_context_t::gralloc_alloc(alloc_device_t* dev, int w, int h, int format,
int usage, buffer_handle_t* pHandle,
int* pStride)
{
if (!dev) {
return -EINVAL;
}
gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, 0);
}
int gpu_context_t::gralloc_alloc_size(alloc_device_t* dev, int w, int h,
int format, int usage,
buffer_handle_t* pHandle, int* pStride,
int bufferSize)
{
if (!dev) {
return -EINVAL;
}
gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
return gpu->alloc_impl(w, h, format, usage, pHandle, pStride, bufferSize);
}
int gpu_context_t::gralloc_free(alloc_device_t* dev,
buffer_handle_t handle)
{
if (private_handle_t::validate(handle) < 0)
return -EINVAL;
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
gpu_context_t* gpu = reinterpret_cast<gpu_context_t*>(dev);
return gpu->free_impl(hnd);
}
/*****************************************************************************/
int gpu_context_t::gralloc_close(struct hw_device_t *dev)
{
gpu_context_t* ctx = reinterpret_cast<gpu_context_t*>(dev);
if (ctx) {
/* TODO: keep a list of all buffer_handle_t created, and free them
* all here.
*/
delete ctx;
}
return 0;
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_GPU_H_
#define GRALLOC_GPU_H_
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <cutils/log.h>
#include "gralloc_priv.h"
#include "fb_priv.h"
namespace gralloc {
class IAllocController;
class gpu_context_t : public alloc_device_t {
public:
gpu_context_t(const private_module_t* module,
IAllocController* alloc_ctrl);
int gralloc_alloc_buffer(unsigned int size, int usage,
buffer_handle_t* pHandle,
int bufferType, int format,
int width, int height);
int free_impl(private_handle_t const* hnd);
int alloc_impl(int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride,
unsigned int bufferSize = 0);
static int gralloc_alloc(alloc_device_t* dev, int w, int h,
int format, int usage,
buffer_handle_t* pHandle,
int* pStride);
int gralloc_alloc_framebuffer_locked(int usage,
buffer_handle_t* pHandle);
int gralloc_alloc_framebuffer(int usage,
buffer_handle_t* pHandle);
static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle);
static int gralloc_alloc_size(alloc_device_t* dev,
int w, int h, int format,
int usage, buffer_handle_t* pHandle,
int* pStride, int bufferSize);
static int gralloc_close(struct hw_device_t *dev);
private:
IAllocController* mAllocCtrl;
void getGrallocInformationFromFormat(int inputFormat,
int *bufferType);
};
}
#endif // GRALLOC_GPU_H

View file

@ -0,0 +1,159 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GR_H_
#define GR_H_
#include <stdint.h>
#include <limits.h>
#include <sys/cdefs.h>
#include <hardware/gralloc.h>
#include <pthread.h>
#include <errno.h>
#include <cutils/native_handle.h>
#include <utils/Singleton.h>
/*****************************************************************************/
struct private_module_t;
struct private_handle_t;
inline unsigned int roundUpToPageSize(unsigned int x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}
template <class Type>
inline Type ALIGN(Type x, Type align) {
return (x + align-1) & ~(align-1);
}
#define FALSE 0
#define TRUE 1
int mapFrameBufferLocked(struct private_module_t* module);
int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
unsigned int getBufferSizeAndDimensions(int width, int height, int format,
int usage, int& alignedw, int &alignedh);
unsigned int getBufferSizeAndDimensions(int width, int height, int format,
int& alignedw, int &alignedh);
// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
void getBufferAttributes(int width, int height, int format, int usage,
int& alignedw, int &alignedh,
int& tileEnabled, unsigned int &size);
bool isMacroTileEnabled(int format, int usage);
int decideBufferHandlingMechanism(int format, const char *compositionUsed,
int hasBlitEngine, int *needConversion,
int *useBufferDirectly);
// Allocate buffer from width, height, format into a private_handle_t
// It is the responsibility of the caller to free the buffer
int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage);
void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
/*****************************************************************************/
class Locker {
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
class Autolock {
Locker& locker;
public:
inline Autolock(Locker& locker) : locker(locker) { locker.lock(); }
inline ~Autolock() { locker.unlock(); }
};
inline Locker() {
pthread_mutex_init(&mutex, 0);
pthread_cond_init(&cond, 0);
}
inline ~Locker() {
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
inline void lock() { pthread_mutex_lock(&mutex); }
inline void wait() { pthread_cond_wait(&cond, &mutex); }
inline void unlock() { pthread_mutex_unlock(&mutex); }
inline void signal() { pthread_cond_signal(&cond); }
};
class AdrenoMemInfo : public android::Singleton <AdrenoMemInfo>
{
public:
AdrenoMemInfo();
~AdrenoMemInfo();
/*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
void getAlignedWidthAndHeight(int width, int height, int format,
int tileEnabled, int& alignedw, int &alignedh);
/*
* Function to return whether GPU support MacroTile feature
*
* @return >0 : supported
* 0 : not supported
*/
int isMacroTilingSupportedByGPU();
private:
// Pointer to the padding library.
void *libadreno_utils;
// link(s)to adreno surface padding library.
int (*LINK_adreno_compute_padding) (int width, int bpp,
int surface_tile_height,
int screen_tile_height,
int padding_threshold);
void (*LINK_adreno_compute_aligned_width_and_height) (int width,
int height,
int bpp,
int tile_mode,
int raster_mode,
int padding_threshold,
int *aligned_w,
int *aligned_h);
int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
void(*LINK_adreno_compute_compressedfmt_aligned_width_and_height)(
int width,
int height,
int format,
int tile_mode,
int raster_mode,
int padding_threshold,
int *aligned_w,
int *aligned_h,
int *bpp);
unsigned int (*LINK_adreno_get_gpu_pixel_alignment) ();
};
#endif /* GR_H_ */

View file

@ -0,0 +1,116 @@
/*
* Copyright (C) 2008, The Android Open Source Project
* Copyright (c) 2011-2012,2016 The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <cutils/properties.h>
#include "gr.h"
#include "gpu.h"
#include "memalloc.h"
#include "alloc_controller.h"
using namespace gralloc;
int fb_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
static int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device);
extern int gralloc_lock(gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int l, int t, int w, int h,
void** vaddr);
extern int gralloc_lock_ycbcr(gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int l, int t, int w, int h,
struct android_ycbcr *ycbcr);
extern int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle);
extern int gralloc_register_buffer(gralloc_module_t const* module,
buffer_handle_t handle);
extern int gralloc_unregister_buffer(gralloc_module_t const* module,
buffer_handle_t handle);
extern int gralloc_perform(struct gralloc_module_t const* module,
int operation, ... );
// HAL module methods
static struct hw_module_methods_t gralloc_module_methods = {
.open = gralloc_device_open
};
// HAL module initialize
struct private_module_t HAL_MODULE_INFO_SYM = {
.base = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = GRALLOC_HARDWARE_MODULE_ID,
.name = "Graphics Memory Allocator Module",
.author = "The Android Open Source Project",
.methods = &gralloc_module_methods,
.dso = 0,
.reserved = {0},
},
.registerBuffer = gralloc_register_buffer,
.unregisterBuffer = gralloc_unregister_buffer,
.lock = gralloc_lock,
.unlock = gralloc_unlock,
.perform = gralloc_perform,
.lock_ycbcr = gralloc_lock_ycbcr,
},
.framebuffer = 0,
.fbFormat = 0,
.flags = 0,
.numBuffers = 0,
.bufferMask = 0,
.lock = PTHREAD_MUTEX_INITIALIZER,
};
// Open Gralloc device
int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
int status = -EINVAL;
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
const private_module_t* m = reinterpret_cast<const private_module_t*>(
module);
gpu_context_t *dev;
IAllocController* alloc_ctrl = IAllocController::getInstance();
dev = new gpu_context_t(m, alloc_ctrl);
if(!dev)
return status;
*device = &dev->common;
status = 0;
} else {
status = fb_device_open(module, name, device);
}
return status;
}

View file

@ -0,0 +1,299 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef GRALLOC_PRIV_H_
#define GRALLOC_PRIV_H_
#include <stdint.h>
#include <limits.h>
#include <sys/cdefs.h>
#include <hardware/gralloc.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <cutils/native_handle.h>
#include <cutils/log.h>
#define ROUND_UP_PAGESIZE(x) ( (((unsigned long)(x)) + PAGE_SIZE-1) & \
(~(PAGE_SIZE-1)) )
enum {
/* gralloc usage bits indicating the type
* of allocation that should be used */
/* SYSTEM heap comes from kernel vmalloc,
* can never be uncached, is not secured*/
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_0,
/* SF heap is used for application buffers, is not secured */
GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP = GRALLOC_USAGE_PRIVATE_1,
/* IOMMU heap comes from manually allocated pages,
* can be cached/uncached, is not secured */
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP = GRALLOC_USAGE_PRIVATE_2,
/* MM heap is a carveout heap for video, can be secured*/
GRALLOC_USAGE_PRIVATE_MM_HEAP = GRALLOC_USAGE_PRIVATE_3,
/* ADSP heap is a carveout heap, is not secured*/
GRALLOC_USAGE_PRIVATE_ADSP_HEAP = 0x01000000,
/* Set this for allocating uncached memory (using O_DSYNC)
* cannot be used with noncontiguous heaps */
GRALLOC_USAGE_PRIVATE_UNCACHED = 0x02000000,
/* Buffer content should be displayed on an primary display only */
GRALLOC_USAGE_PRIVATE_INTERNAL_ONLY = 0x04000000,
/* Buffer content should be displayed on an external display only */
GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY = 0x08000000,
/* This flag is set for WFD usecase */
GRALLOC_USAGE_PRIVATE_WFD = 0x00200000,
/* CAMERA heap is a carveout heap for camera, is not secured*/
GRALLOC_USAGE_PRIVATE_CAMERA_HEAP = 0x00400000,
/* This flag is used for SECURE display usecase */
GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY = 0x00800000,
};
enum {
/* Gralloc perform enums
*/
GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
// This will be deprecated from latest graphics drivers. This is kept
// for those backward compatibility i.e., newer Display HAL + older graphics
// libraries
GRALLOC_MODULE_PERFORM_GET_STRIDE,
GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE,
GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE,
GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO,
};
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP |\
GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |\
GRALLOC_USAGE_PRIVATE_MM_HEAP |\
GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
#define INTERLACE_MASK 0x80
#define S3D_FORMAT_MASK 0xFF000
/*****************************************************************************/
enum {
/* OEM specific HAL formats */
HAL_PIXEL_FORMAT_RGBA_5551 = 6,
HAL_PIXEL_FORMAT_RGBA_4444 = 7,
HAL_PIXEL_FORMAT_NV12_ENCODEABLE = 0x102,
HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS = 0x7FA30C04,
HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED = 0x7FA30C03,
HAL_PIXEL_FORMAT_YCbCr_420_SP = 0x109,
HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO = 0x7FA30C01,
HAL_PIXEL_FORMAT_YCrCb_422_SP = 0x10B,
HAL_PIXEL_FORMAT_R_8 = 0x10D,
HAL_PIXEL_FORMAT_RG_88 = 0x10E,
HAL_PIXEL_FORMAT_YCbCr_444_SP = 0x10F,
HAL_PIXEL_FORMAT_YCrCb_444_SP = 0x110,
HAL_PIXEL_FORMAT_YCrCb_422_I = 0x111,
HAL_PIXEL_FORMAT_BGRX_8888 = 0x112,
HAL_PIXEL_FORMAT_NV21_ZSL = 0x113,
HAL_PIXEL_FORMAT_INTERLACE = 0x180,
//v4l2_fourcc('Y', 'U', 'Y', 'L'). 24 bpp YUYV 4:2:2 10 bit per component
HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT = 0x4C595559,
//v4l2_fourcc('Y', 'B', 'W', 'C'). 10 bit per component. This compressed
//format reduces the memory access bandwidth
HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED = 0x43574259,
//Khronos ASTC formats
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC,
HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC,
HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD,
};
/* possible formats for 3D content*/
enum {
HAL_NO_3D = 0x0000,
HAL_3D_IN_SIDE_BY_SIDE_L_R = 0x10000,
HAL_3D_IN_TOP_BOTTOM = 0x20000,
HAL_3D_IN_INTERLEAVE = 0x40000,
HAL_3D_IN_SIDE_BY_SIDE_R_L = 0x80000,
HAL_3D_OUT_SIDE_BY_SIDE = 0x1000,
HAL_3D_OUT_TOP_BOTTOM = 0x2000,
HAL_3D_OUT_INTERLEAVE = 0x4000,
HAL_3D_OUT_MONOSCOPIC = 0x8000
};
enum {
BUFFER_TYPE_UI = 0,
BUFFER_TYPE_VIDEO
};
/*****************************************************************************/
#ifdef __cplusplus
struct private_handle_t : public native_handle {
#else
struct private_handle_t {
native_handle_t nativeHandle;
#endif
enum {
PRIV_FLAGS_FRAMEBUFFER = 0x00000001,
PRIV_FLAGS_USES_PMEM = 0x00000002,
PRIV_FLAGS_USES_PMEM_ADSP = 0x00000004,
PRIV_FLAGS_USES_ION = 0x00000008,
PRIV_FLAGS_USES_ASHMEM = 0x00000010,
PRIV_FLAGS_NEEDS_FLUSH = 0x00000020,
PRIV_FLAGS_INTERNAL_ONLY = 0x00000040,
PRIV_FLAGS_NON_CPU_WRITER = 0x00000080,
PRIV_FLAGS_NONCONTIGUOUS_MEM = 0x00000100,
PRIV_FLAGS_CACHED = 0x00000200,
PRIV_FLAGS_SECURE_BUFFER = 0x00000400,
// For explicit synchronization
PRIV_FLAGS_UNSYNCHRONIZED = 0x00000800,
// Not mapped in userspace
PRIV_FLAGS_NOT_MAPPED = 0x00001000,
// Display on external only
PRIV_FLAGS_EXTERNAL_ONLY = 0x00002000,
PRIV_FLAGS_VIDEO_ENCODER = 0x00010000,
PRIV_FLAGS_CAMERA_WRITE = 0x00020000,
PRIV_FLAGS_CAMERA_READ = 0x00040000,
PRIV_FLAGS_HW_COMPOSER = 0x00080000,
PRIV_FLAGS_HW_TEXTURE = 0x00100000,
PRIV_FLAGS_ITU_R_601 = 0x00200000,
PRIV_FLAGS_ITU_R_601_FR = 0x00400000,
PRIV_FLAGS_ITU_R_709 = 0x00800000,
PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
// Buffer is rendered in Tile Format
PRIV_FLAGS_TILE_RENDERED = 0x02000000,
// Buffer rendered using CPU/SW renderer
PRIV_FLAGS_CPU_RENDERED = 0x04000000
};
// file-descriptors
int fd;
int fd_metadata; // fd for the meta-data
// ints
int magic;
int flags;
unsigned int size;
unsigned int offset;
int bufferType;
uint64_t base __attribute__((aligned(8)));
unsigned int offset_metadata;
// The gpu address mapped into the mmu.
uint64_t gpuaddr __attribute__((aligned(8)));
int format;
int width;
int height;
uint64_t base_metadata __attribute__((aligned(8)));
#ifdef __cplusplus
static const int sNumFds = 2;
static inline int sNumInts() {
return ((sizeof(private_handle_t) - sizeof(native_handle_t)) /
sizeof(int)) - sNumFds;
}
static const int sMagic = 'gmsm';
private_handle_t(int fd, unsigned int size, int flags, int bufferType,
int format, int width, int height, int eFd = -1,
unsigned int eOffset = 0, uint64_t eBase = 0) :
fd(fd), fd_metadata(eFd), magic(sMagic),
flags(flags), size(size), offset(0), bufferType(bufferType),
base(0), offset_metadata(eOffset), gpuaddr(0),
format(format), width(width), height(height),
base_metadata(eBase)
{
version = (int) sizeof(native_handle);
numInts = sNumInts();
numFds = sNumFds;
}
~private_handle_t() {
base_metadata = 0;
magic = 0;
fd_metadata = 0;
}
bool usesPhysicallyContiguousMemory() {
return (flags & PRIV_FLAGS_USES_PMEM) != 0;
}
static int validate(const native_handle* h) {
const private_handle_t* hnd = (const private_handle_t*)h;
if (!h || h->version != sizeof(native_handle) ||
h->numInts != sNumInts() || h->numFds != sNumFds ||
hnd->magic != sMagic)
{
ALOGE("Invalid gralloc handle (at %p): "
"ver(%d/%zu) ints(%d/%d) fds(%d/%d)"
"magic(%c%c%c%c/%c%c%c%c)",
h,
h ? h->version : -1, sizeof(native_handle),
h ? h->numInts : -1, sNumInts(),
h ? h->numFds : -1, sNumFds,
hnd ? (((hnd->magic >> 24) & 0xFF)?
((hnd->magic >> 24) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 16) & 0xFF)?
((hnd->magic >> 16) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 8) & 0xFF)?
((hnd->magic >> 8) & 0xFF) : '-') : '?',
hnd ? (((hnd->magic >> 0) & 0xFF)?
((hnd->magic >> 0) & 0xFF) : '-') : '?',
(sMagic >> 24) & 0xFF,
(sMagic >> 16) & 0xFF,
(sMagic >> 8) & 0xFF,
(sMagic >> 0) & 0xFF);
return -EINVAL;
}
return 0;
}
static private_handle_t* dynamicCast(const native_handle* in) {
if (validate(in) == 0) {
return (private_handle_t*) in;
}
return NULL;
}
#endif
};
#endif /* GRALLOC_PRIV_H_ */

View file

@ -0,0 +1,239 @@
/*
* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define DEBUG 0
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>
#include <cutils/log.h>
#include <errno.h>
#include <utils/Trace.h>
#include "gralloc_priv.h"
#include "ionalloc.h"
using gralloc::IonAlloc;
#define ION_DEVICE "/dev/ion"
int IonAlloc::open_device()
{
if(mIonFd == FD_INIT)
mIonFd = open(ION_DEVICE, O_RDONLY);
if(mIonFd < 0 ) {
ALOGE("%s: Failed to open ion device - %s",
__FUNCTION__, strerror(errno));
mIonFd = FD_INIT;
return -errno;
}
return 0;
}
void IonAlloc::close_device()
{
if(mIonFd >= 0)
close(mIonFd);
mIonFd = FD_INIT;
}
int IonAlloc::alloc_buffer(alloc_data& data)
{
ATRACE_CALL();
Locker::Autolock _l(mLock);
int err = 0;
struct ion_handle_data handle_data;
struct ion_fd_data fd_data;
struct ion_allocation_data ionAllocData;
void *base = 0;
ionAllocData.len = data.size;
ionAllocData.align = data.align;
ionAllocData.heap_id_mask = data.flags & ~ION_SECURE;
ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED;
// ToDo: replace usage of alloc data structure with
// ionallocdata structure.
if (data.flags & ION_SECURE)
ionAllocData.flags |= ION_SECURE;
err = open_device();
if (err)
return err;
if(ioctl(mIonFd, ION_IOC_ALLOC, &ionAllocData)) {
err = -errno;
ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
return err;
}
fd_data.handle = ionAllocData.handle;
handle_data.handle = ionAllocData.handle;
if(ioctl(mIonFd, ION_IOC_MAP, &fd_data)) {
err = -errno;
ALOGE("%s: ION_IOC_MAP failed with error - %s",
__FUNCTION__, strerror(errno));
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
return err;
}
if(!(data.flags & ION_SECURE)) {
base = mmap(0, ionAllocData.len, PROT_READ|PROT_WRITE,
MAP_SHARED, fd_data.fd, 0);
if(base == MAP_FAILED) {
err = -errno;
ALOGE("%s: Failed to map the allocated memory: %s",
__FUNCTION__, strerror(errno));
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
return err;
}
}
data.base = base;
data.fd = fd_data.fd;
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
ALOGD_IF(DEBUG, "ion: Allocated buffer base:%p size:%zu fd:%d",
data.base, ionAllocData.len, data.fd);
return 0;
}
int IonAlloc::free_buffer(void* base, unsigned int size, unsigned int offset,
int fd)
{
ATRACE_CALL();
Locker::Autolock _l(mLock);
ALOGD_IF(DEBUG, "ion: Freeing buffer base:%p size:%u fd:%d",
base, size, fd);
int err = 0;
err = open_device();
if (err)
return err;
if(base)
err = unmap_buffer(base, size, offset);
close(fd);
return err;
}
int IonAlloc::map_buffer(void **pBase, unsigned int size, unsigned int offset,
int fd)
{
ATRACE_CALL();
int err = 0;
void *base = 0;
// It is a (quirky) requirement of ION to have opened the
// ion fd in the process that is doing the mapping
err = open_device();
if (err)
return err;
base = mmap(0, size, PROT_READ| PROT_WRITE,
MAP_SHARED, fd, 0);
*pBase = base;
if(base == MAP_FAILED) {
err = -errno;
ALOGE("ion: Failed to map memory in the client: %s",
strerror(errno));
} else {
ALOGD_IF(DEBUG, "ion: Mapped buffer base:%p size:%u offset:%u fd:%d",
base, size, offset, fd);
}
return err;
}
int IonAlloc::unmap_buffer(void *base, unsigned int size,
unsigned int /*offset*/)
{
ATRACE_CALL();
ALOGD_IF(DEBUG, "ion: Unmapping buffer base:%p size:%u", base, size);
int err = 0;
if(munmap(base, size)) {
err = -errno;
ALOGE("ion: Failed to unmap memory at %p : %s",
base, strerror(errno));
}
return err;
}
int IonAlloc::clean_buffer(void *base, unsigned int size, unsigned int offset,
int fd, int op)
{
ATRACE_CALL();
ATRACE_INT("operation id", op);
struct ion_flush_data flush_data;
struct ion_fd_data fd_data;
struct ion_handle_data handle_data;
int err = 0;
err = open_device();
if (err)
return err;
fd_data.fd = fd;
if (ioctl(mIonFd, ION_IOC_IMPORT, &fd_data)) {
err = -errno;
ALOGE("%s: ION_IOC_IMPORT failed with error - %s",
__FUNCTION__, strerror(errno));
return err;
}
handle_data.handle = fd_data.handle;
flush_data.handle = fd_data.handle;
flush_data.vaddr = base;
// offset and length are unsigned int
flush_data.offset = offset;
flush_data.length = size;
struct ion_custom_data d;
switch(op) {
case CACHE_CLEAN:
d.cmd = ION_IOC_CLEAN_CACHES;
break;
case CACHE_INVALIDATE:
d.cmd = ION_IOC_INV_CACHES;
break;
case CACHE_CLEAN_AND_INVALIDATE:
default:
d.cmd = ION_IOC_CLEAN_INV_CACHES;
}
d.arg = (unsigned long int)&flush_data;
if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
err = -errno;
ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
__FUNCTION__, strerror(errno));
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
return err;
}
ioctl(mIonFd, ION_IOC_FREE, &handle_data);
return 0;
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRALLOC_IONALLOC_H
#define GRALLOC_IONALLOC_H
#include <linux/msm_ion.h>
#include "memalloc.h"
#include "gr.h"
namespace gralloc {
class IonAlloc : public IMemAlloc {
public:
virtual int alloc_buffer(alloc_data& data);
virtual int free_buffer(void *base, unsigned int size,
unsigned int offset, int fd);
virtual int map_buffer(void **pBase, unsigned int size,
unsigned int offset, int fd);
virtual int unmap_buffer(void *base, unsigned int size,
unsigned int offset);
virtual int clean_buffer(void*base, unsigned int size,
unsigned int offset, int fd, int op);
IonAlloc() { mIonFd = FD_INIT; }
~IonAlloc() { close_device(); }
private:
int mIonFd;
int open_device();
void close_device();
mutable Locker mLock;
};
}
#endif /* GRALLOC_IONALLOC_H */

View file

@ -0,0 +1,444 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2011-2014,2016 The Linux Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#include <limits.h>
#include <errno.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <utils/Trace.h>
#include <hardware/hardware.h>
#include <hardware/gralloc.h>
#include "gralloc_priv.h"
#include "gr.h"
#include "alloc_controller.h"
#include "memalloc.h"
#include <qdMetaData.h>
using namespace gralloc;
/*****************************************************************************/
// Return the type of allocator -
// these are used for mapping/unmapping
static IMemAlloc* getAllocator(int flags)
{
IMemAlloc* memalloc;
IAllocController* alloc_ctrl = IAllocController::getInstance();
memalloc = alloc_ctrl->getAllocator(flags);
return memalloc;
}
static int gralloc_map(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
if(!module)
return -EINVAL;
private_handle_t* hnd = (private_handle_t*)handle;
unsigned int size = 0;
int err = 0;
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
void *mappedAddress;
// Dont map FRAMEBUFFER and SECURE_BUFFERS
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
!(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
size = hnd->size;
err = memalloc->map_buffer(&mappedAddress, size,
hnd->offset, hnd->fd);
if(err || mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap handle %p, fd=%d (%s)",
handle, hnd->fd, strerror(errno));
hnd->base = 0;
return -errno;
}
hnd->base = uint64_t(mappedAddress) + hnd->offset;
}
//Allow mapping of metadata for all buffers and SECURE_BUFFER
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
mappedAddress = MAP_FAILED;
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
err = memalloc->map_buffer(&mappedAddress, size,
hnd->offset_metadata, hnd->fd_metadata);
if(err || mappedAddress == MAP_FAILED) {
ALOGE("Could not mmap handle %p, fd=%d (%s)",
handle, hnd->fd_metadata, strerror(errno));
hnd->base_metadata = 0;
return -errno;
}
hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
}
return 0;
}
static int gralloc_unmap(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
if(!module)
return -EINVAL;
private_handle_t* hnd = (private_handle_t*)handle;
if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
int err = -EINVAL;
void* base = (void*)hnd->base;
unsigned int size = hnd->size;
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
if(memalloc != NULL) {
err = memalloc->unmap_buffer(base, size, hnd->offset);
if (err) {
ALOGE("Could not unmap memory at address %p", (void*)base);
}
base = (void*)hnd->base_metadata;
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
err = memalloc->unmap_buffer(base, size, hnd->offset_metadata);
if (err) {
ALOGE("Could not unmap memory at address %p", (void*)base);
}
}
}
/* need to initialize the pointer to NULL otherwise unmapping for that
* buffer happens twice which leads to crash */
hnd->base = 0;
hnd->base_metadata = 0;
return 0;
}
/*****************************************************************************/
static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
/*****************************************************************************/
int gralloc_register_buffer(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
// In this implementation, we don't need to do anything here
/* NOTE: we need to initialize the buffer as not mapped/not locked
* because it shouldn't when this function is called the first time
* in a new process. Ideally these flags shouldn't be part of the
* handle, but instead maintained in the kernel or at least
* out-of-line
*/
private_handle_t* hnd = (private_handle_t*)handle;
hnd->base = 0;
hnd->base_metadata = 0;
int err = gralloc_map(module, handle);
if (err) {
ALOGE("%s: gralloc_map failed", __FUNCTION__);
return err;
}
return 0;
}
int gralloc_unregister_buffer(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
/*
* If the buffer has been mapped during a lock operation, it's time
* to un-map it. It's an error to be here with a locked buffer.
* NOTE: the framebuffer is handled differently and is never unmapped.
*/
private_handle_t* hnd = (private_handle_t*)handle;
if (hnd->base != 0) {
gralloc_unmap(module, handle);
}
hnd->base = 0;
hnd->base_metadata = 0;
return 0;
}
int terminateBuffer(gralloc_module_t const* module,
private_handle_t* hnd)
{
ATRACE_CALL();
if(!module)
return -EINVAL;
/*
* If the buffer has been mapped during a lock operation, it's time
* to un-map it. It's an error to be here with a locked buffer.
*/
if (hnd->base != 0) {
// this buffer was mapped, unmap it now
if (hnd->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP |
private_handle_t::PRIV_FLAGS_USES_ASHMEM |
private_handle_t::PRIV_FLAGS_USES_ION)) {
gralloc_unmap(module, hnd);
} else {
ALOGE("terminateBuffer: unmapping a non pmem/ashmem buffer flags = 0x%x",
hnd->flags);
gralloc_unmap(module, hnd);
}
}
return 0;
}
static int gralloc_map_and_invalidate (gralloc_module_t const* module,
buffer_handle_t handle, int usage)
{
ATRACE_CALL();
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
int err = 0;
private_handle_t* hnd = (private_handle_t*)handle;
if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
if (hnd->base == 0) {
// we need to map for real
pthread_mutex_t* const lock = &sMapLock;
pthread_mutex_lock(lock);
err = gralloc_map(module, handle);
pthread_mutex_unlock(lock);
}
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
hnd->flags & private_handle_t::PRIV_FLAGS_CACHED) {
//Invalidate if CPU reads in software and there are non-CPU
//writers. No need to do this for the metadata buffer as it is
//only read/written in software.
if ((usage & GRALLOC_USAGE_SW_READ_MASK) and
(hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER))
{
IMemAlloc* memalloc = getAllocator(hnd->flags) ;
err = memalloc->clean_buffer((void*)hnd->base,
hnd->size, hnd->offset, hnd->fd,
CACHE_INVALIDATE);
}
//Mark the buffer to be flushed after CPU write.
if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
}
}
return err;
}
int gralloc_lock(gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int /*l*/, int /*t*/, int /*w*/, int /*h*/,
void** vaddr)
{
ATRACE_CALL();
private_handle_t* hnd = (private_handle_t*)handle;
int err = gralloc_map_and_invalidate(module, handle, usage);
if(!err)
*vaddr = (void*)hnd->base;
return err;
}
int gralloc_lock_ycbcr(gralloc_module_t const* module,
buffer_handle_t handle, int usage,
int /*l*/, int /*t*/, int /*w*/, int /*h*/,
struct android_ycbcr *ycbcr)
{
ATRACE_CALL();
private_handle_t* hnd = (private_handle_t*)handle;
int err = gralloc_map_and_invalidate(module, handle, usage);
if(!err)
err = getYUVPlaneInfo(hnd, ycbcr);
return err;
}
int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle)
{
ATRACE_CALL();
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
int err = 0;
private_handle_t* hnd = (private_handle_t*)handle;
IMemAlloc* memalloc = getAllocator(hnd->flags);
if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
err = memalloc->clean_buffer((void*)hnd->base,
hnd->size, hnd->offset, hnd->fd,
CACHE_CLEAN);
hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
}
return err;
}
/*****************************************************************************/
int gralloc_perform(struct gralloc_module_t const* module,
int operation, ... )
{
int res = -EINVAL;
va_list args;
if(!module)
return res;
va_start(args, operation);
switch (operation) {
case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
{
int fd = va_arg(args, int);
unsigned int size = va_arg(args, unsigned int);
unsigned int offset = va_arg(args, unsigned int);
void* base = va_arg(args, void*);
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
native_handle_t** handle = va_arg(args, native_handle_t**);
private_handle_t* hnd = (private_handle_t*)native_handle_create(
private_handle_t::sNumFds, private_handle_t::sNumInts());
if (hnd) {
hnd->magic = private_handle_t::sMagic;
hnd->fd = fd;
hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
hnd->size = size;
hnd->offset = offset;
hnd->base = uint64_t(base) + offset;
hnd->gpuaddr = 0;
hnd->width = width;
hnd->height = height;
hnd->format = format;
*handle = (native_handle_t *)hnd;
res = 0;
}
break;
}
case GRALLOC_MODULE_PERFORM_GET_STRIDE:
{
int width = va_arg(args, int);
int format = va_arg(args, int);
int *stride = va_arg(args, int *);
int alignedw = 0, alignedh = 0;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
0, format, false, alignedw, alignedh);
*stride = alignedw;
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
int *stride = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
va_end(args);
return res;
}
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
*stride = metadata->bufferDim.sliceWidth;
} else {
*stride = hnd->width;
}
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
int *stride = va_arg(args, int *);
int *height = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
va_end(args);
return res;
}
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
*stride = metadata->bufferDim.sliceWidth;
*height = metadata->bufferDim.sliceHeight;
} else {
*stride = hnd->width;
*height = hnd->height;
}
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
{
int width = va_arg(args, int);
int height = va_arg(args, int);
int format = va_arg(args, int);
int usage = va_arg(args, int);
int *alignedWidth = va_arg(args, int *);
int *alignedHeight = va_arg(args, int *);
int *tileEnabled = va_arg(args,int *);
*tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height, format, *tileEnabled, *alignedWidth,
*alignedHeight);
res = 0;
} break;
case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
int *color_space = va_arg(args, int *);
if (private_handle_t::validate(hnd)) {
va_end(args);
return res;
}
MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
*color_space = metadata->colorSpace;
res = 0;
}
} break;
case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
android_ycbcr* ycbcr = va_arg(args, struct android_ycbcr *);
if (!private_handle_t::validate(hnd)) {
res = getYUVPlaneInfo(hnd, ycbcr);
}
} break;
default:
break;
}
va_end(args);
return res;
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRALLOC_MEMALLOC_H
#define GRALLOC_MEMALLOC_H
#include <stdlib.h>
namespace gralloc {
enum {
CACHE_CLEAN = 0x1,
CACHE_INVALIDATE,
CACHE_CLEAN_AND_INVALIDATE,
};
struct alloc_data {
void *base;
int fd;
unsigned int offset;
unsigned int size;
unsigned int align;
uintptr_t pHandle;
bool uncached;
unsigned int flags;
int allocType;
};
class IMemAlloc {
public:
// Allocate buffer - fill in the alloc_data
// structure and pass it in. Mapped address
// and fd are returned in the alloc_data struct
virtual int alloc_buffer(alloc_data& data) = 0;
// Free buffer
virtual int free_buffer(void *base, unsigned int size,
unsigned int offset, int fd) = 0;
// Map buffer
virtual int map_buffer(void **pBase, unsigned int size,
unsigned int offset, int fd) = 0;
// Unmap buffer
virtual int unmap_buffer(void *base, unsigned int size,
unsigned int offset) = 0;
// Clean and invalidate
virtual int clean_buffer(void *base, unsigned int size,
unsigned int offset, int fd, int op) = 0;
// Destructor
virtual ~IMemAlloc() {};
enum {
FD_INIT = -1,
};
};
} // end gralloc namespace
#endif // GRALLOC_MEMALLOC_H