upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
49
android/hardware/qcom/display/msm8909/libgralloc/Android.mk
Normal file
49
android/hardware/qcom/display/msm8909/libgralloc/Android.mk
Normal 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)
|
190
android/hardware/qcom/display/msm8909/libgralloc/NOTICE
Normal file
190
android/hardware/qcom/display/msm8909/libgralloc/NOTICE
Normal 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
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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
|
56
android/hardware/qcom/display/msm8909/libgralloc/fb_priv.h
Normal file
56
android/hardware/qcom/display/msm8909/libgralloc/fb_priv.h
Normal 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 */
|
455
android/hardware/qcom/display/msm8909/libgralloc/framebuffer.cpp
Normal file
455
android/hardware/qcom/display/msm8909/libgralloc/framebuffer.cpp
Normal 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;
|
||||
}
|
402
android/hardware/qcom/display/msm8909/libgralloc/gpu.cpp
Normal file
402
android/hardware/qcom/display/msm8909/libgralloc/gpu.cpp
Normal 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;
|
||||
}
|
||||
|
74
android/hardware/qcom/display/msm8909/libgralloc/gpu.h
Normal file
74
android/hardware/qcom/display/msm8909/libgralloc/gpu.h
Normal 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
|
159
android/hardware/qcom/display/msm8909/libgralloc/gr.h
Normal file
159
android/hardware/qcom/display/msm8909/libgralloc/gr.h
Normal 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_ */
|
116
android/hardware/qcom/display/msm8909/libgralloc/gralloc.cpp
Normal file
116
android/hardware/qcom/display/msm8909/libgralloc/gralloc.cpp
Normal 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;
|
||||
}
|
299
android/hardware/qcom/display/msm8909/libgralloc/gralloc_priv.h
Normal file
299
android/hardware/qcom/display/msm8909/libgralloc/gralloc_priv.h
Normal 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_ */
|
239
android/hardware/qcom/display/msm8909/libgralloc/ionalloc.cpp
Normal file
239
android/hardware/qcom/display/msm8909/libgralloc/ionalloc.cpp
Normal 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;
|
||||
}
|
||||
|
74
android/hardware/qcom/display/msm8909/libgralloc/ionalloc.h
Normal file
74
android/hardware/qcom/display/msm8909/libgralloc/ionalloc.h
Normal 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 */
|
||||
|
444
android/hardware/qcom/display/msm8909/libgralloc/mapper.cpp
Normal file
444
android/hardware/qcom/display/msm8909/libgralloc/mapper.cpp
Normal 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;
|
||||
}
|
89
android/hardware/qcom/display/msm8909/libgralloc/memalloc.h
Normal file
89
android/hardware/qcom/display/msm8909/libgralloc/memalloc.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue