gralloc960: Update to the r9p0 gralloc release
This is necessary in order to support r9p0 libGLES_mali.so binaries.
NOTE: This unfortunately drops recent changes like v4.12+ ION abi
compatibility, which will need to be re-implemented and re-added.
NOTE: This change requires both kernel changes for the r9p0 driver
as well as binariy r9p0 libGLES_mali.so libraries. Don't merge until
those are all lined up to land.
Change-Id: I6c7fdf7585edea08196d1a323db3ec0629883311
Signed-off-by: John Stultz <john.stultz@linaro.org>
diff --git a/gralloc960/mali_gralloc_bufferaccess.cpp b/gralloc960/mali_gralloc_bufferaccess.cpp
new file mode 100644
index 0000000..ea77283
--- /dev/null
+++ b/gralloc960/mali_gralloc_bufferaccess.cpp
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
+ *
+ * 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.
+ */
+#include <errno.h>
+#include <inttypes.h>
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+#include <hardware/gralloc1.h>
+#else
+#include <hardware/gralloc.h>
+#endif
+
+#include "mali_gralloc_module.h"
+#include "mali_gralloc_private_interface_types.h"
+#include "mali_gralloc_buffer.h"
+#include "mali_gralloc_formats.h"
+#include "mali_gralloc_usages.h"
+#include "mali_gralloc_ion.h"
+#include "gralloc_helper.h"
+#include <sync/sync.h>
+
+int mali_gralloc_lock(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w, int h,
+ void **vaddr)
+{
+ GRALLOC_UNUSED(m);
+ GRALLOC_UNUSED(l);
+ GRALLOC_UNUSED(t);
+ GRALLOC_UNUSED(w);
+ GRALLOC_UNUSED(h);
+
+ if (private_handle_t::validate(buffer) < 0)
+ {
+ AERR("Locking invalid buffer %p, returning error", buffer);
+ return -EINVAL;
+ }
+
+ private_handle_t *hnd = (private_handle_t *)buffer;
+
+ if (hnd->req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
+ {
+ AERR("Buffers with format YCbCr_420_888 must be locked using (*lock_ycbcr)");
+ return -EINVAL;
+ }
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+ {
+ hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+ }
+
+ if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
+ {
+ *vaddr = (void *)hnd->base;
+ }
+
+ return 0;
+}
+
+int mali_gralloc_lock_ycbcr(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+ int h, android_ycbcr *ycbcr)
+{
+ GRALLOC_UNUSED(m);
+ GRALLOC_UNUSED(l);
+ GRALLOC_UNUSED(t);
+ GRALLOC_UNUSED(w);
+ GRALLOC_UNUSED(h);
+
+ if (private_handle_t::validate(buffer) < 0)
+ {
+ AERR("Locking invalid buffer %p, returning error", buffer);
+ return -EINVAL;
+ }
+
+ if (NULL == ycbcr)
+ {
+ return -EINVAL;
+ }
+
+ private_handle_t *hnd = (private_handle_t *)buffer;
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+ {
+ hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+ }
+
+ if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
+ !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
+ {
+ char *base = (char *)hnd->base;
+ int y_stride = hnd->byte_stride;
+ /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
+ int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
+ int y_size = y_stride * adjusted_height;
+
+ int u_offset = 0;
+ int v_offset = 0;
+ int c_stride = 0;
+ int step = 0;
+
+ uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+ switch (base_format)
+ {
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+ c_stride = y_stride;
+ /* Y plane, UV plane */
+ u_offset = y_size;
+ v_offset = y_size + 1;
+ step = 2;
+ break;
+
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+ c_stride = y_stride;
+ /* Y plane, UV plane */
+ v_offset = y_size;
+ u_offset = y_size + 1;
+ step = 2;
+ break;
+
+ case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+ {
+ int c_size;
+
+ /* Stride alignment set to 16 as the SW access flags were set */
+ c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
+ c_size = c_stride * (adjusted_height / 2);
+ /* Y plane, V plane, U plane */
+ v_offset = y_size;
+ u_offset = y_size + c_size;
+ step = 1;
+ break;
+ }
+
+ default:
+ AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
+ return -EINVAL;
+ }
+
+ ycbcr->y = base;
+ ycbcr->cb = base + u_offset;
+ ycbcr->cr = base + v_offset;
+ ycbcr->ystride = y_stride;
+ ycbcr->cstride = c_stride;
+ ycbcr->chroma_step = step;
+ }
+ else
+ {
+ AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int mali_gralloc_unlock(const mali_gralloc_module *m, buffer_handle_t buffer)
+{
+ if (private_handle_t::validate(buffer) < 0)
+ {
+ AERR("Unlocking invalid buffer %p, returning error", buffer);
+ return -EINVAL;
+ }
+
+ private_handle_t *hnd = (private_handle_t *)buffer;
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner)
+ {
+ mali_gralloc_ion_sync(m, hnd);
+ }
+
+ return 0;
+}
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+int mali_gralloc_get_num_flex_planes(const mali_gralloc_module *m, buffer_handle_t buffer, uint32_t *num_planes)
+{
+ GRALLOC_UNUSED(m);
+
+ if (private_handle_t::validate(buffer) < 0)
+ {
+ AERR("Invalid buffer %p, returning error", buffer);
+ return -EINVAL;
+ }
+
+ if (NULL == num_planes)
+ {
+ return -EINVAL;
+ }
+
+ private_handle_t *hnd = (private_handle_t *)buffer;
+ uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+ switch (base_format)
+ {
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+ case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+ *num_planes = 3;
+ break;
+
+ default:
+ AERR("Can't get planes number of buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+int mali_gralloc_lock_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t, int w,
+ int h, void **vaddr, int32_t fence_fd)
+{
+ if (fence_fd >= 0)
+ {
+ sync_wait(fence_fd, -1);
+ close(fence_fd);
+ }
+
+ return mali_gralloc_lock(m, buffer, usage, l, t, w, h, vaddr);
+}
+
+int mali_gralloc_lock_ycbcr_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+ int w, int h, android_ycbcr *ycbcr, int32_t fence_fd)
+{
+ if (fence_fd >= 0)
+ {
+ sync_wait(fence_fd, -1);
+ close(fence_fd);
+ }
+
+ return mali_gralloc_lock_ycbcr(m, buffer, usage, l, t, w, h, ycbcr);
+}
+
+#if GRALLOC_USE_GRALLOC1_API == 1
+
+int mali_gralloc_lock_flex_async(const mali_gralloc_module *m, buffer_handle_t buffer, uint64_t usage, int l, int t,
+ int w, int h, struct android_flex_layout *flex_layout, int32_t fence_fd)
+{
+ GRALLOC_UNUSED(m);
+ GRALLOC_UNUSED(l);
+ GRALLOC_UNUSED(t);
+ GRALLOC_UNUSED(w);
+ GRALLOC_UNUSED(h);
+
+ if (private_handle_t::validate(buffer) < 0)
+ {
+ AERR("Locking invalid buffer %p, returning error", buffer);
+ return -EINVAL;
+ }
+
+ if (NULL == flex_layout)
+ {
+ return -EINVAL;
+ }
+
+ if (fence_fd >= 0)
+ {
+ sync_wait(fence_fd, -1);
+ close(fence_fd);
+ }
+
+ private_handle_t *hnd = (private_handle_t *)buffer;
+
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION)
+ {
+ hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+ }
+
+ if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK) &&
+ !(hnd->internal_format & MALI_GRALLOC_INTFMT_EXT_MASK))
+ {
+ uint8_t *base = (uint8_t *)hnd->base;
+ int y_stride = hnd->byte_stride;
+ /* Ensure height is aligned for subsampled chroma before calculating buffer parameters */
+ int adjusted_height = GRALLOC_ALIGN(hnd->height, 2);
+ int y_size = y_stride * adjusted_height;
+
+ uint64_t base_format = hnd->internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;
+
+ switch (base_format)
+ {
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
+ flex_layout->format = FLEX_FORMAT_YCbCr;
+ flex_layout->num_planes = 3;
+ flex_layout->planes[0].top_left = base;
+ flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+ flex_layout->planes[0].bits_per_component = 8;
+ flex_layout->planes[0].bits_used = 8;
+ flex_layout->planes[0].h_increment = 1;
+ flex_layout->planes[0].v_increment = y_stride;
+ flex_layout->planes[0].h_subsampling = 1;
+ flex_layout->planes[0].v_subsampling = 1;
+ flex_layout->planes[1].top_left = base + y_size;
+ flex_layout->planes[1].component = FLEX_COMPONENT_Cb;
+ flex_layout->planes[1].bits_per_component = 8;
+ flex_layout->planes[1].bits_used = 8;
+ flex_layout->planes[1].h_increment = 2;
+ flex_layout->planes[1].v_increment = y_stride;
+ flex_layout->planes[1].h_subsampling = 2;
+ flex_layout->planes[1].v_subsampling = 2;
+ flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
+ flex_layout->planes[2].component = FLEX_COMPONENT_Cr;
+ flex_layout->planes[2].bits_per_component = 8;
+ flex_layout->planes[2].bits_used = 8;
+ flex_layout->planes[2].h_increment = 2;
+ flex_layout->planes[2].v_increment = y_stride;
+ flex_layout->planes[2].h_subsampling = 2;
+ flex_layout->planes[2].v_subsampling = 2;
+ break;
+
+ case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
+ flex_layout->format = FLEX_FORMAT_YCbCr;
+ flex_layout->num_planes = 3;
+ flex_layout->planes[0].top_left = base;
+ flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+ flex_layout->planes[0].bits_per_component = 8;
+ flex_layout->planes[0].bits_used = 8;
+ flex_layout->planes[0].h_increment = 1;
+ flex_layout->planes[0].v_increment = y_stride;
+ flex_layout->planes[0].h_subsampling = 1;
+ flex_layout->planes[0].v_subsampling = 1;
+ flex_layout->planes[1].top_left = base + y_size;
+ flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
+ flex_layout->planes[1].bits_per_component = 8;
+ flex_layout->planes[1].bits_used = 8;
+ flex_layout->planes[1].h_increment = 2;
+ flex_layout->planes[1].v_increment = y_stride;
+ flex_layout->planes[1].h_subsampling = 2;
+ flex_layout->planes[1].v_subsampling = 2;
+ flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + 1;
+ flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
+ flex_layout->planes[2].bits_per_component = 8;
+ flex_layout->planes[2].bits_used = 8;
+ flex_layout->planes[2].h_increment = 2;
+ flex_layout->planes[2].v_increment = y_stride;
+ flex_layout->planes[2].h_subsampling = 2;
+ flex_layout->planes[2].v_subsampling = 2;
+ break;
+
+ case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
+ {
+ int c_size;
+ int c_stride;
+ /* Stride alignment set to 16 as the SW access flags were set */
+ c_stride = GRALLOC_ALIGN(hnd->byte_stride / 2, 16);
+ c_size = c_stride * (adjusted_height / 2);
+ /* Y plane, V plane, U plane */
+ flex_layout->format = FLEX_FORMAT_YCbCr;
+ flex_layout->num_planes = 3;
+ flex_layout->planes[0].top_left = base;
+ flex_layout->planes[0].component = FLEX_COMPONENT_Y;
+ flex_layout->planes[0].bits_per_component = 8;
+ flex_layout->planes[0].bits_used = 8;
+ flex_layout->planes[0].h_increment = 1;
+ flex_layout->planes[0].v_increment = y_stride;
+ flex_layout->planes[0].h_subsampling = 1;
+ flex_layout->planes[0].v_subsampling = 1;
+ flex_layout->planes[1].top_left = base + y_size;
+ flex_layout->planes[1].component = FLEX_COMPONENT_Cr;
+ flex_layout->planes[1].bits_per_component = 8;
+ flex_layout->planes[1].bits_used = 8;
+ flex_layout->planes[1].h_increment = 1;
+ flex_layout->planes[1].v_increment = c_stride;
+ flex_layout->planes[1].h_subsampling = 2;
+ flex_layout->planes[1].v_subsampling = 2;
+ flex_layout->planes[2].top_left = flex_layout->planes[1].top_left + c_size;
+ flex_layout->planes[2].component = FLEX_COMPONENT_Cb;
+ flex_layout->planes[2].bits_per_component = 8;
+ flex_layout->planes[2].bits_used = 8;
+ flex_layout->planes[2].h_increment = 1;
+ flex_layout->planes[2].v_increment = c_stride;
+ flex_layout->planes[2].h_subsampling = 2;
+ flex_layout->planes[2].v_subsampling = 2;
+ break;
+ }
+
+ default:
+ AERR("Can't lock buffer %p: wrong format %" PRIx64, hnd, hnd->internal_format);
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ AERR("Don't support to lock buffer %p: with format %" PRIx64, hnd, hnd->internal_format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+int mali_gralloc_unlock_async(const mali_gralloc_module *m, buffer_handle_t buffer, int32_t *fence_fd)
+{
+ *fence_fd = -1;
+
+ if (mali_gralloc_unlock(m, buffer) < 0)
+ {
+ return -EINVAL;
+ }
+
+ return 0;
+}