175f0d3110b04346b901771f96ce15cdbe907278fYang Ni/*
275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Copyright (C) 2016 The Android Open Source Project
375f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Licensed under the Apache License, Version 2.0 (the "License");
575f0d3110b04346b901771f96ce15cdbe907278fYang Ni * you may not use this file except in compliance with the License.
675f0d3110b04346b901771f96ce15cdbe907278fYang Ni * You may obtain a copy of the License at
775f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
875f0d3110b04346b901771f96ce15cdbe907278fYang Ni *      http://www.apache.org/licenses/LICENSE-2.0
975f0d3110b04346b901771f96ce15cdbe907278fYang Ni *
1075f0d3110b04346b901771f96ce15cdbe907278fYang Ni * Unless required by applicable law or agreed to in writing, software
1175f0d3110b04346b901771f96ce15cdbe907278fYang Ni * distributed under the License is distributed on an "AS IS" BASIS,
1275f0d3110b04346b901771f96ce15cdbe907278fYang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375f0d3110b04346b901771f96ce15cdbe907278fYang Ni * See the License for the specific language governing permissions and
1475f0d3110b04346b901771f96ce15cdbe907278fYang Ni * limitations under the License.
1575f0d3110b04346b901771f96ce15cdbe907278fYang Ni */
1675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
1775f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovAllocation.h"
1875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
1975f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsAllocation.h"
2075f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsContext.h"
2175f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsCppUtils.h"
2275f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsElement.h"
2375f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsType.h"
2475f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovContext.h"
2575f0d3110b04346b901771f96ce15cdbe907278fYang Ni#include "rsovCore.h"
2675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
2775f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace android {
2875f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace renderscript {
2975f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace rsov {
3075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3175f0d3110b04346b901771f96ce15cdbe907278fYang Ninamespace {
3275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
3375f0d3110b04346b901771f96ce15cdbe907278fYang Nisize_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
3475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // For the flexible YCbCr format, layout is initialized during call to
3575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // Allocation::ioReceive.  Return early and avoid clobberring any
3675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // pre-existing layout.
3775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
3875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return 0;
3975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
4075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
4175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // YUV only supports basic 2d
4275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // so we can stash the plane pointers in the mipmap levels.
4375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t uvSize = 0;
4475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->lod[1].dimX = state->lod[0].dimX / 2;
4575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->lod[1].dimY = state->lod[0].dimY / 2;
4675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->lod[2].dimX = state->lod[0].dimX / 2;
4775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->lod[2].dimY = state->lod[0].dimY / 2;
4875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->yuv.shift = 1;
4975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->yuv.step = 1;
5075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  state->lodCount = 3;
5175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
5275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  switch (yuv) {
5375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    case HAL_PIXEL_FORMAT_YV12:
5475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
5575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
5675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                (state->lod[0].stride * state->lod[0].dimY);
5775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uvSize += state->lod[2].stride * state->lod[2].dimY;
5875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
5975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[1].stride = state->lod[2].stride;
6075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
6175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                (state->lod[2].stride * state->lod[2].dimY);
6275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uvSize += state->lod[1].stride * state->lod[2].dimY;
6375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      break;
6475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
6575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      // state->lod[1].dimX = state->lod[0].dimX;
6675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[1].stride = state->lod[0].stride;
6775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[2].stride = state->lod[0].stride;
6875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
6975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                (state->lod[0].stride * state->lod[0].dimY);
7075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) + 1;
7175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uvSize += state->lod[1].stride * state->lod[1].dimY;
7275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      state->yuv.step = 2;
7375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      break;
7475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    default:
7575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      rsAssert(0);
7675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
7775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
7875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return uvSize;
7975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
8075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
8175f0d3110b04346b901771f96ce15cdbe907278fYang Ni// TODO: Dedup this with the same code under frameworks/rs/driver
8275f0d3110b04346b901771f96ce15cdbe907278fYang Nisize_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
8375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                   const Type *type, uint8_t *ptr,
8475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                   size_t requiredAlignment) {
8575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].dimX = type->getDimX();
8675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].dimY = type->getDimY();
8775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
8875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].mallocPtr = 0;
8975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // Stride needs to be aligned to a boundary defined by requiredAlignment!
9075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t stride =
9175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
9275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
9375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lodCount = type->getLODCount();
9475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.faceCount = type->getDimFaces();
9575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t offsets[Allocation::MAX_LOD];
9775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  memset(offsets, 0, sizeof(offsets));
9875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
9975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t o = alloc->mHal.drvState.lod[0].stride *
10075f0d3110b04346b901771f96ce15cdbe907278fYang Ni             rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
10175f0d3110b04346b901771f96ce15cdbe907278fYang Ni             rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
10275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.state.yuv) {
10375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
10475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
10575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
10675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
10775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
10875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  } else if (alloc->mHal.drvState.lodCount > 1) {
10975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
11075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
11175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
11275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
11375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->mHal.drvState.lod[lod].dimX = tx;
11475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->mHal.drvState.lod[lod].dimY = ty;
11575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->mHal.drvState.lod[lod].dimZ = tz;
11675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->mHal.drvState.lod[lod].stride =
11775f0d3110b04346b901771f96ce15cdbe907278fYang Ni          rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
11875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      offsets[lod] = o;
11975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
12075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (tx > 1) tx >>= 1;
12175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (ty > 1) ty >>= 1;
12275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (tz > 1) tz >>= 1;
12375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
12475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
12575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
12675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.faceOffset = o;
12775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
12875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drvState.lod[0].mallocPtr = ptr;
12975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
13075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
13175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
13275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
13375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t allocSize = alloc->mHal.drvState.faceOffset;
13475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.drvState.faceCount) {
13575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    allocSize *= 6;
13675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
13775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
13875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return allocSize;
13975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
14075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14175f0d3110b04346b901771f96ce15cdbe907278fYang Nisize_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
14275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                   const Type *type, uint8_t *ptr) {
14375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return AllocationBuildPointerTable(rsc, alloc, type, ptr,
14475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                     Allocation::kMinimumRSAlignment);
14575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
14675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
14775f0d3110b04346b901771f96ce15cdbe907278fYang Niuint8_t *GetOffsetPtr(const Allocation *alloc, uint32_t xoff, uint32_t yoff,
14875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                      uint32_t zoff, uint32_t lod,
14975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                      RsAllocationCubemapFace face) {
15075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
15175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += face * alloc->mHal.drvState.faceOffset;
15275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += zoff * alloc->mHal.drvState.lod[lod].dimY *
15375f0d3110b04346b901771f96ce15cdbe907278fYang Ni         alloc->mHal.drvState.lod[lod].stride;
15475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
15575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += xoff * alloc->mHal.state.elementSizeBytes;
15675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return ptr;
15775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
15875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
15975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
16075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
16175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
16275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
16375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t y = 0; y < h; y++) {
16475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
16575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint16_t *i1 =
16675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2, lod, face);
16775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint16_t *i2 =
16875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2 + 1, lod, face);
16975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
17075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t x = 0; x < w; x++) {
17175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
17275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      oPtr++;
17375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i1 += 2;
17475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i2 += 2;
17575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
17675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
17775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
17875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
17975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
18075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
18175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
18275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
18375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t y = 0; y < h; y++) {
18475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
18575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint32_t *i1 =
18675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        (uint32_t *)GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
18775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint32_t *i2 =
18875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        (uint32_t *)GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
18975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
19075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t x = 0; x < w; x++) {
19175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
19275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      oPtr++;
19375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i1 += 2;
19475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i2 += 2;
19575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
19675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
19775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
19875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
19975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
20075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
20175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
20275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t y = 0; y < h; y++) {
20475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
20575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint8_t *i1 = GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
20675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint8_t *i2 = GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
20775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
20875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t x = 0; x < w; x++) {
20975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
21075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      oPtr++;
21175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i1 += 2;
21275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      i2 += 2;
21375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
21475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
21575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
21675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // anonymous namespace
21875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
21930dfb1368d0a3440cfedc882c27cc236d799f77cYang NiRSoVAllocation::RSoVAllocation(RSoVContext *context, const Type *type,
220a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung                               size_t bufferSize)
221a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung    : mBuffer(new RSoVBuffer(context, bufferSize)),
22275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      mType(type),
22375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      mWidth(type->getDimX()),
22475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      mHeight(type->getDimY()),
225a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung      mDepth(type->getDimZ()) {}
226a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung
227a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) SungRSoVBuffer::RSoVBuffer(RSoVContext *context, size_t size)
228a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung    : mRSoV(context), mDevice(context->getDevice()) {
22930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  InitBuffer(size);
23075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
23175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
232a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) SungRSoVBuffer::~RSoVBuffer() {
233a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung  vkUnmapMemory(mDevice, mMem);
23430dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  vkDestroyBuffer(mDevice, mBuf, nullptr);
23575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  vkFreeMemory(mDevice, mMem, nullptr);
23675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
23775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
238a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sungvoid RSoVBuffer::InitBuffer(size_t bufferSize) {
239f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  VkResult res;
240f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
241f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  VkBufferCreateInfo buf_info = {
24230dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
24330dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .pNext = nullptr,
24430dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
24530dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .size = bufferSize,
24630dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .queueFamilyIndexCount = 0,
24730dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .pQueueFamilyIndices = nullptr,
24830dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
24930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .flags = 0,
250f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  };
251f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  res = vkCreateBuffer(mDevice, &buf_info, nullptr, &mBuf);
252f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  rsAssert(res == VK_SUCCESS);
253f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
254f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  VkMemoryRequirements mem_reqs;
255f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  vkGetBufferMemoryRequirements(mDevice, mBuf, &mem_reqs);
256f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
257f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  VkMemoryAllocateInfo allocateInfo = {
25830dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
25930dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .pNext = nullptr,
26030dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .memoryTypeIndex = 0,
26130dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni      .allocationSize = mem_reqs.size,
262f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  };
263f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
264f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  bool pass;
265a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung  pass =
266a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung      mRSoV->MemoryTypeFromProperties(mem_reqs.memoryTypeBits,
267a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung                                      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
268a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung                                          VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
269a456a6e0672896ef7b8d312d8013208ae4086ab2I-Jui (Ray) Sung                                      &allocateInfo.memoryTypeIndex);
270f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  rsAssert(pass);
271f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
272f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  // TODO: Make this aligned
273f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  res = vkAllocateMemory(mDevice, &allocateInfo, nullptr, &mMem);
274f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  rsAssert(res == VK_SUCCESS);
275f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
276f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  res = vkBindBufferMemory(mDevice, mBuf, mMem, 0);
277f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  rsAssert(res == VK_SUCCESS);
278f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
279f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  mBufferInfo.buffer = mBuf;
280f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  mBufferInfo.offset = 0;
281f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  mBufferInfo.range = bufferSize;
282f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
283f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  res = vkMapMemory(mDevice, mMem, 0, mem_reqs.size, 0, (void **)&mPtr);
284f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni  rsAssert(res == VK_SUCCESS);
285f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni}
286f15ce3de10aa8edf30d9c2dca60237a3d24eddccYang Ni
28775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace rsov
28875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace renderscript
28975f0d3110b04346b901771f96ce15cdbe907278fYang Ni}  // namespace android
29075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
29175f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Allocation;
29275f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Context;
29375f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Element;
29475f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::Type;
29575f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rs_allocation;
29675f0d3110b04346b901771f96ce15cdbe907278fYang Niusing android::renderscript::rsMax;
29775f0d3110b04346b901771f96ce15cdbe907278fYang Niusing namespace android::renderscript::rsov;
29875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
29975f0d3110b04346b901771f96ce15cdbe907278fYang Nibool rsovAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
30075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVHal *hal = static_cast<RSoVHal *>(rsc->mHal.drv);
30175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVContext *rsov = hal->mRSoV;
30275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const Type *type = alloc->getType();
30375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
30430dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  // Calculate the object size.
30530dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  size_t allocSize = AllocationBuildPointerTable(rsc, alloc, type, nullptr);
30630dfb1368d0a3440cfedc882c27cc236d799f77cYang Ni  RSoVAllocation *rsovAlloc = new RSoVAllocation(rsov, type, allocSize);
30775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drv = rsovAlloc;
30875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  AllocationBuildPointerTable(rsc, alloc, type,
30975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              (uint8_t *)rsovAlloc->getHostPtr());
31075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return true;
31175f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
31275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
31375f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationDestroy(const Context *rsc, Allocation *alloc) {
31475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  RSoVAllocation *rsovAlloc = static_cast<RSoVAllocation *>(alloc->mHal.drv);
31575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  delete rsovAlloc;
31675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  alloc->mHal.drv = nullptr;
31775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
31875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
31975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData1D(const Context *rsc, const Allocation *alloc,
32075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t lod, size_t count,
32175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          const void *data, size_t sizeBytes) {
32275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
32375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint8_t *ptr =
32475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
32575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t size = count * eSize;
32675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (ptr != data) {
32775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Skip the copy if we are the same allocation. This can arise from
32875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // our Bitmap optimization, where we share the same storage.
32975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    if (alloc->mHal.state.hasReferences) {
33075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->incRefs(data, count);
33175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      alloc->decRefs(ptr, count);
33275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
33375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    memcpy(ptr, data, size);
33475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
33575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
33675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
33775f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData2D(const Context *rsc, const Allocation *alloc,
33875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t yoff, uint32_t lod,
33975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          RsAllocationCubemapFace face, uint32_t w, uint32_t h,
34075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          const void *data, size_t sizeBytes, size_t stride) {
34175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t eSize = alloc->mHal.state.elementSizeBytes;
34275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t lineSize = eSize * w;
34375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!stride) {
34475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    stride = lineSize;
34575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
34675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
34775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.drvState.lod[0].mallocPtr) {
34875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint8_t *src = static_cast<const uint8_t *>(data);
34975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
35075f0d3110b04346b901771f96ce15cdbe907278fYang Ni
35175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t line = yoff; line < (yoff + h); line++) {
35275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (alloc->mHal.state.hasReferences) {
35375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        alloc->incRefs(src, w);
35475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        alloc->decRefs(dst, w);
35575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
35675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      memcpy(dst, src, lineSize);
35775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      src += stride;
35875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      dst += alloc->mHal.drvState.lod[lod].stride;
35975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
36075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // TODO: handle YUV Allocations
36175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    if (alloc->mHal.state.yuv) {
36275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      size_t clineSize = lineSize;
36375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      int lod = 1;
36475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      int maxLod = 2;
36575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YV12) {
36675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        maxLod = 3;
36775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        clineSize >>= 1;
36875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      } else if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
36975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        lod = 2;
37075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        maxLod = 3;
37175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
37275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
37375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      while (lod < maxLod) {
37475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
37575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
37675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        for (uint32_t line = (yoff >> 1); line < ((yoff + h) >> 1); line++) {
37775f0d3110b04346b901771f96ce15cdbe907278fYang Ni          memcpy(dst, src, clineSize);
37875f0d3110b04346b901771f96ce15cdbe907278fYang Ni          // When copying from an array to an Allocation, the src pointer
37975f0d3110b04346b901771f96ce15cdbe907278fYang Ni          // to the array should just move by the number of bytes copied.
38075f0d3110b04346b901771f96ce15cdbe907278fYang Ni          src += clineSize;
38175f0d3110b04346b901771f96ce15cdbe907278fYang Ni          dst += alloc->mHal.drvState.lod[lod].stride;
38275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
38375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        lod++;
38475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
38575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
38675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
38775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
38875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
38975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData3D(const Context *rsc, const Allocation *alloc,
39075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t yoff, uint32_t zoff,
39175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
39275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          const void *data, size_t sizeBytes, size_t stride) {
39375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t eSize = alloc->mHal.state.elementSizeBytes;
39475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t lineSize = eSize * w;
39575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!stride) {
39675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    stride = lineSize;
39775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
39875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
39975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.drvState.lod[0].mallocPtr) {
40075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint8_t *src = static_cast<const uint8_t *>(data);
40175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t z = zoff; z < (d + zoff); z++) {
40275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
40375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                  RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
40475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      for (uint32_t line = yoff; line < (yoff + h); line++) {
40575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        if (alloc->mHal.state.hasReferences) {
40675f0d3110b04346b901771f96ce15cdbe907278fYang Ni          alloc->incRefs(src, w);
40775f0d3110b04346b901771f96ce15cdbe907278fYang Ni          alloc->decRefs(dst, w);
40875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        }
40975f0d3110b04346b901771f96ce15cdbe907278fYang Ni        memcpy(dst, src, lineSize);
41075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        src += stride;
41175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        dst += alloc->mHal.drvState.lod[lod].stride;
41275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
41375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
41475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
41575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
41675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
41775f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationRead1D(const Context *rsc, const Allocation *alloc,
41875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t lod, size_t count, void *data,
41975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          size_t sizeBytes) {
42075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
42175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const uint8_t *ptr =
42275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
42375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (data != ptr) {
42475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // Skip the copy if we are the same allocation. This can arise from
42575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    // our Bitmap optimization, where we share the same storage.
42675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    memcpy(data, ptr, count * eSize);
42775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
42875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
42975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
43075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationRead2D(const Context *rsc, const Allocation *alloc,
43175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t yoff, uint32_t lod,
43275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          RsAllocationCubemapFace face, uint32_t w, uint32_t h,
43375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          void *data, size_t sizeBytes, size_t stride) {
43475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t eSize = alloc->mHal.state.elementSizeBytes;
43575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t lineSize = eSize * w;
43675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!stride) {
43775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    stride = lineSize;
43875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
43975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
44075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.drvState.lod[0].mallocPtr) {
44175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *dst = static_cast<uint8_t *>(data);
44275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
44375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    if (dst == src) {
44475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      // Skip the copy if we are the same allocation. This can arise from
44575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      // our Bitmap optimization, where we share the same storage.
44675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      return;
44775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
44875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
44975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t line = yoff; line < (yoff + h); line++) {
45075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      memcpy(dst, src, lineSize);
45175f0d3110b04346b901771f96ce15cdbe907278fYang Ni      dst += stride;
45275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      src += alloc->mHal.drvState.lod[lod].stride;
45375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
45475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  } else {
45575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    ALOGE("Add code to readback from non-script memory");
45675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
45775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
45875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
45975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationRead3D(const Context *rsc, const Allocation *alloc,
46075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t xoff, uint32_t yoff, uint32_t zoff,
46175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
46275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          void *data, size_t sizeBytes, size_t stride) {
46375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t eSize = alloc->mHal.state.elementSizeBytes;
46475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t lineSize = eSize * w;
46575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!stride) {
46675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    stride = lineSize;
46775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
46875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
46975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.drvState.lod[0].mallocPtr) {
47075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *dst = static_cast<uint8_t *>(data);
47175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t z = zoff; z < (d + zoff); z++) {
47275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
47375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                        RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
47475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      if (dst == src) {
47575f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // Skip the copy if we are the same allocation. This can arise from
47675f0d3110b04346b901771f96ce15cdbe907278fYang Ni        // our Bitmap optimization, where we share the same storage.
47775f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return;
47875f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
47975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
48075f0d3110b04346b901771f96ce15cdbe907278fYang Ni      for (uint32_t line = yoff; line < (yoff + h); line++) {
48175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        memcpy(dst, src, lineSize);
48275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        dst += stride;
48375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        src += alloc->mHal.drvState.lod[lod].stride;
48475f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
48575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
48675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
48775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
48875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
48975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid *rsovAllocationLock1D(const Context *rsc, const Allocation *alloc) {
49075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return alloc->mHal.drvState.lod[0].mallocPtr;
49175f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
49275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
49375f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationUnlock1D(const Context *rsc, const Allocation *alloc) {}
49475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
49575f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData1D_alloc(const Context *rsc, const Allocation *dstAlloc,
49675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t dstXoff, uint32_t dstLod, size_t count,
49775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                const Allocation *srcAlloc, uint32_t srcXoff,
49875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t srcLod) {}
49975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
50075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData2D_alloc_script(
50175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
50275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
50375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
50475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
50575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
50675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t i = 0; i < h; i++) {
50775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *dstPtr =
50875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
50975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint8_t *srcPtr =
51075f0d3110b04346b901771f96ce15cdbe907278fYang Ni        GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
51175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    memcpy(dstPtr, srcPtr, w * elementSize);
51275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
51375f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
51475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
51575f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData3D_alloc_script(
51675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
51775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod, uint32_t w, uint32_t h,
51875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t d, const Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff,
51975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t srcZoff, uint32_t srcLod) {
52075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
52175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t j = 0; j < d; j++) {
52275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t i = 0; i < h; i++) {
52375f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uint8_t *dstPtr =
52475f0d3110b04346b901771f96ce15cdbe907278fYang Ni          GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j, dstLod,
52575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                       RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
52675f0d3110b04346b901771f96ce15cdbe907278fYang Ni      uint8_t *srcPtr =
52775f0d3110b04346b901771f96ce15cdbe907278fYang Ni          GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j, srcLod,
52875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                       RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
52975f0d3110b04346b901771f96ce15cdbe907278fYang Ni      memcpy(dstPtr, srcPtr, w * elementSize);
53075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
53175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
53275f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
53375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
53475f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData2D_alloc(
53575f0d3110b04346b901771f96ce15cdbe907278fYang Ni    const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
53675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
53775f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
53875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
53975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
54075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    rsc->setError(RS_ERROR_FATAL_DRIVER,
54175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                  "Non-script allocation copies not "
54275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                  "yet implemented.");
54375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return;
54475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
54575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsovAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstLod,
54675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                    dstFace, w, h, srcAlloc, srcXoff, srcYoff,
54775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                    srcLod, srcFace);
54875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
54975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
55075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationData3D_alloc(const Context *rsc, const Allocation *dstAlloc,
55175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t dstXoff, uint32_t dstYoff,
55275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t dstZoff, uint32_t dstLod, uint32_t w,
55375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t h, uint32_t d,
55475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                const Allocation *srcAlloc, uint32_t srcXoff,
55575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t srcYoff, uint32_t srcZoff,
55675f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                uint32_t srcLod) {
55775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
55875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    rsc->setError(RS_ERROR_FATAL_DRIVER,
55975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                  "Non-script allocation copies not "
56075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                  "yet implemented.");
56175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return;
56275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
56375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsovAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
56475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                    dstLod, w, h, d, srcAlloc, srcXoff, srcYoff,
56575f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                    srcZoff, srcLod);
56675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
56775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
56875f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
56975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // Get a base pointer to the new LOD
57075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const Allocation *base = alloc->mHal.state.baseAlloc;
57175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const Type *type = alloc->mHal.state.type;
57275f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (base == nullptr) {
57375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return;
57475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
57575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
57675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const int lodBias = alloc->mHal.state.originLOD;
57775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t lodCount = rsMax(alloc->mHal.drvState.lodCount, (uint32_t)1);
57875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t lod = 0; lod < lodCount; lod++) {
57975f0d3110b04346b901771f96ce15cdbe907278fYang Ni    alloc->mHal.drvState.lod[lod] = base->mHal.drvState.lod[lod + lodBias];
58075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    alloc->mHal.drvState.lod[lod].mallocPtr = GetOffsetPtr(
58175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        alloc, alloc->mHal.state.originX, alloc->mHal.state.originY,
58275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        alloc->mHal.state.originZ, lodBias,
58375f0d3110b04346b901771f96ce15cdbe907278fYang Ni        (RsAllocationCubemapFace)alloc->mHal.state.originFace);
58475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
58575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
58675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
58775f0d3110b04346b901771f96ce15cdbe907278fYang Nibool rsovAllocationAdapterInit(const Context *rsc, Allocation *alloc) {
58875f0d3110b04346b901771f96ce15cdbe907278fYang Ni// TODO: may need a RSoV Allocation here
58975f0d3110b04346b901771f96ce15cdbe907278fYang Ni#if 0
59075f0d3110b04346b901771f96ce15cdbe907278fYang Ni    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
59175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    if (!drv) {
59275f0d3110b04346b901771f96ce15cdbe907278fYang Ni        return false;
59375f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
59475f0d3110b04346b901771f96ce15cdbe907278fYang Ni    alloc->mHal.drv = drv;
59575f0d3110b04346b901771f96ce15cdbe907278fYang Ni#endif
59675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // We need to build an allocation that looks like a subset of the parent
59775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // allocation
59875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  rsovAllocationAdapterOffset(rsc, alloc);
59975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
60075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return true;
60175f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
60275f0d3110b04346b901771f96ce15cdbe907278fYang Ni
60375f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationSyncAll(const Context *rsc, const Allocation *alloc,
60475f0d3110b04346b901771f96ce15cdbe907278fYang Ni                           RsAllocationUsageType src) {
60575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: anything to do here?
60675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
60775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
60875f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
60975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: anything to do here?
61075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
61175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
61275f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationResize(const Context *rsc, const Allocation *alloc,
61375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                          const Type *newType, bool zeroNew) {
61475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
61575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // can this be done without copying, if the new size is greater than the
61675f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // original?
61775f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
61875f0d3110b04346b901771f96ce15cdbe907278fYang Ni
61975f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationGenerateMipmaps(const Context *rsc,
62075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                   const Allocation *alloc) {
62175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (!alloc->mHal.drvState.lod[0].mallocPtr) {
62275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    return;
62375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
62475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
62575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  for (uint32_t face = 0; face < numFaces; face++) {
62675f0d3110b04346b901771f96ce15cdbe907278fYang Ni    for (uint32_t lod = 0; lod < (alloc->getType()->getLODCount() - 1); lod++) {
62775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      switch (alloc->getType()->getElement()->getSizeBits()) {
62875f0d3110b04346b901771f96ce15cdbe907278fYang Ni        case 32:
62975f0d3110b04346b901771f96ce15cdbe907278fYang Ni          mip8888(alloc, lod, (RsAllocationCubemapFace)face);
63075f0d3110b04346b901771f96ce15cdbe907278fYang Ni          break;
63175f0d3110b04346b901771f96ce15cdbe907278fYang Ni        case 16:
63275f0d3110b04346b901771f96ce15cdbe907278fYang Ni          mip565(alloc, lod, (RsAllocationCubemapFace)face);
63375f0d3110b04346b901771f96ce15cdbe907278fYang Ni          break;
63475f0d3110b04346b901771f96ce15cdbe907278fYang Ni        case 8:
63575f0d3110b04346b901771f96ce15cdbe907278fYang Ni          mip8(alloc, lod, (RsAllocationCubemapFace)face);
63675f0d3110b04346b901771f96ce15cdbe907278fYang Ni          break;
63775f0d3110b04346b901771f96ce15cdbe907278fYang Ni      }
63875f0d3110b04346b901771f96ce15cdbe907278fYang Ni    }
63975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
64075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
64175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
64275f0d3110b04346b901771f96ce15cdbe907278fYang Niuint32_t rsovAllocationGrallocBits(const Context *rsc, Allocation *alloc) {
64375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  return 0;
64475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
64575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
64675f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationUpdateCachedObject(const Context *rsc,
64775f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                      const Allocation *alloc,
64875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                                      rs_allocation *obj) {
64975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  obj->p = alloc;
65075f0d3110b04346b901771f96ce15cdbe907278fYang Ni#ifdef __LP64__
651700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused1 = nullptr;
652700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused2 = nullptr;
653700e68883c4324c15b380ff6724249f39d4f498cI-Jui (Ray) Sung  obj->unused3 = nullptr;
65475f0d3110b04346b901771f96ce15cdbe907278fYang Ni#endif
65575f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
65675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
65775f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationSetSurface(const Context *rsc, Allocation *alloc,
65875f0d3110b04346b901771f96ce15cdbe907278fYang Ni                              ANativeWindow *nw) {
65975f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
66075f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
66175f0d3110b04346b901771f96ce15cdbe907278fYang Ni
66275f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationIoSend(const Context *rsc, Allocation *alloc) {
66375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
66475f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
66575f0d3110b04346b901771f96ce15cdbe907278fYang Ni
66675f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationIoReceive(const Context *rsc, Allocation *alloc) {
66775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  // TODO: implement this
66875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
66975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
67075f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationElementData(const Context *rsc, const Allocation *alloc,
67175f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               uint32_t x, uint32_t y, uint32_t z,
67275f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               const void *data, uint32_t cIdx,
67375f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               size_t sizeBytes) {
67475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint8_t *ptr =
67575f0d3110b04346b901771f96ce15cdbe907278fYang Ni      GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
67675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
67775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
67875f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
67975f0d3110b04346b901771f96ce15cdbe907278fYang Ni
68075f0d3110b04346b901771f96ce15cdbe907278fYang Ni  if (alloc->mHal.state.hasReferences) {
68175f0d3110b04346b901771f96ce15cdbe907278fYang Ni    e->incRefs(data);
68275f0d3110b04346b901771f96ce15cdbe907278fYang Ni    e->decRefs(ptr);
68375f0d3110b04346b901771f96ce15cdbe907278fYang Ni  }
68475f0d3110b04346b901771f96ce15cdbe907278fYang Ni
68575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  memcpy(ptr, data, sizeBytes);
68675f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
68775f0d3110b04346b901771f96ce15cdbe907278fYang Ni
68875f0d3110b04346b901771f96ce15cdbe907278fYang Nivoid rsovAllocationElementRead(const Context *rsc, const Allocation *alloc,
68975f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               uint32_t x, uint32_t y, uint32_t z, void *data,
69075f0d3110b04346b901771f96ce15cdbe907278fYang Ni                               uint32_t cIdx, size_t sizeBytes) {
69175f0d3110b04346b901771f96ce15cdbe907278fYang Ni  uint8_t *ptr =
69275f0d3110b04346b901771f96ce15cdbe907278fYang Ni      GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
69375f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69475f0d3110b04346b901771f96ce15cdbe907278fYang Ni  const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
69575f0d3110b04346b901771f96ce15cdbe907278fYang Ni  ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
69675f0d3110b04346b901771f96ce15cdbe907278fYang Ni
69775f0d3110b04346b901771f96ce15cdbe907278fYang Ni  memcpy(data, ptr, sizeBytes);
69875f0d3110b04346b901771f96ce15cdbe907278fYang Ni}
699