rsdAllocation.cpp revision 10f317038dd53543dc8c7f5afe26a6360adfb5f3
13a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray/*
2c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Copyright (C) 2013 The Android Open Source Project
3f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *      http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
17c383a500aa59423264811be3874461bf8adbfea0Zonr Chang#include "rsdCore.h"
186315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "rsdAllocation.h"
19462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "rsAllocation.h"
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
22462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "system/window.h"
24e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "ui/Rect.h"
25e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "ui/GraphicBufferMapper.h"
26d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines#endif
27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#ifdef RS_COMPATIBILITY_LIB
29462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include "rsCompatibilityLib.h"
306315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#else
3189273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang#include "rsdFrameBufferObj.h"
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "gui/GLConsumer.h"
338d5a2f6ab321615bfb3a46f68aff0b643a71caa0Raphael#include "gui/CpuConsumer.h"
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "gui/Surface.h"
356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "hardware/gralloc.h"
36593a894650e81be54173106ec266f0311cebebd3Stephen Hines
376315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <GLES/gl.h>
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include <GLES2/gl2.h>
394cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include <GLES/glext.h>
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif
416315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifdef RS_SERVER
439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// server requires malloc.h for memalign
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#include <malloc.h>
452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
46462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletusing namespace android;
48462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaousing namespace android::renderscript;
493a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
503a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
513a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray#ifndef RS_COMPATIBILITY_LIB
522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletconst static GLenum gFaceOrder[] = {
532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
55462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet};
602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
61462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei LiaoGLenum rsdTypeToGLType(RsDataType t) {
622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    switch (t) {
63a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
651f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;
662ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
67d2936939ec10879e25746322db60071f79f28c1bStephen Hines    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
70462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    case RS_TYPE_SIGNED_8:      return GL_BYTE;
729ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    case RS_TYPE_SIGNED_16:     return GL_SHORT;
73462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    default:    break;
74e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    }
75462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    return 0;
76c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
77c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
78c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc BrouilletGLenum rsdKindToGLFormat(RsDataKind k) {
79c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    switch (k) {
80c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
81c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_A: return GL_ALPHA;
82c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
83c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_RGB: return GL_RGB;
84c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
85c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
86c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    default: break;
87c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    }
88c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    return 0;
89c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
90c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet#endif
91c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
92c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletuint8_t *GetOffsetPtr(const android::renderscript::Allocation *alloc,
93c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                      uint32_t xoff, uint32_t yoff, uint32_t zoff,
94c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                      uint32_t lod, RsAllocationCubemapFace face) {
95c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
96c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    ptr += face * alloc->mHal.drvState.faceOffset;
97c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    ptr += zoff * alloc->mHal.drvState.lod[lod].dimY * alloc->mHal.drvState.lod[lod].stride;
98c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
99c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    ptr += xoff * alloc->mHal.state.elementSizeBytes;
100c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    return ptr;
101c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
102c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
103c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
104c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouilletstatic void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
105c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                            uint32_t xoff, uint32_t yoff, uint32_t lod,
106c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet                            RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
10792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang#ifndef RS_COMPATIBILITY_LIB
1082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsAssert(drv->textureID);
11192b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
11292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
11392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    GLenum t = GL_TEXTURE_2D;
1142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.hasFaces) {
1152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        t = gFaceOrder[face];
11692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    }
1176e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
11892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang#endif
11992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
12092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
1216e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines
1222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
1232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstatic void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
1242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
127324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
1282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1296e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    uint32_t faceCount = 1;
130324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    if (alloc->mHal.state.hasFaces) {
1319ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        faceCount = 6;
132324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
133324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao
1349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    rsdGLCheckError(rsc, "Upload2DTexture 1 ");
1356315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    for (uint32_t face = 0; face < faceCount; face ++) {
1362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
1372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            const uint8_t *p = GetOffsetPtr(alloc, 0, 0, 0, lod, (RsAllocationCubemapFace)face);
1382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            GLenum t = GL_TEXTURE_2D;
1402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            if (alloc->mHal.state.hasFaces) {
1412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                t = gFaceOrder[face];
1422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            }
1432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1442ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            if (isFirstUpload) {
1452ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
1462ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                             alloc->mHal.state.type->getLODDimX(lod),
1472ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                             alloc->mHal.state.type->getLODDimY(lod),
1482ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                             0, drv->glFormat, drv->glType, p);
1492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            } else {
1502ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
1512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                alloc->mHal.state.type->getLODDimX(lod),
1522ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                alloc->mHal.state.type->getLODDimY(lod),
1532ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                drv->glFormat, drv->glType, p);
1542ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            }
1552ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
1562ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
1592ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
1602ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsdGLCheckError(rsc, "Upload2DTexture");
1622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
1632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
1642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1652ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstatic void UploadToTexture(const Context *rsc, const Allocation *alloc) {
1669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#ifndef RS_COMPATIBILITY_LIB
1679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
1702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (!drv->textureID) {
1719ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
1726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        }
1739ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
174462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
175462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
176d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    if (!drv->glType || !drv->glFormat) {
1779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
1782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1802ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!alloc->mHal.drvState.lod[0].mallocPtr) {
1812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        return;
1822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    bool isFirstUpload = false;
1859ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!drv->textureID) {
1872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
1882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        isFirstUpload = true;
1892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    Upload2DTexture(rsc, alloc, isFirstUpload);
1922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
1932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
1942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (alloc->mHal.drvState.lod[0].mallocPtr) {
1952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            free(alloc->mHal.drvState.lod[0].mallocPtr);
1962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            alloc->mHal.drvState.lod[0].mallocPtr = NULL;
1972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
1982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
1992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsdGLCheckError(rsc, "UploadToTexture");
2002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
2012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
2022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstatic void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
2042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
2052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
2062ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (!drv->glFormat) {
2082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        return;
2092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
2102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!drv->renderTargetID) {
2122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);
2132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        if (!drv->renderTargetID) {
215462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            // This should generally not happen
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
217462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            rsc->dumpDebug();
218462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            return;
219cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao        }
220cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao        RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
2212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
2222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                    alloc->mHal.drvState.lod[0].dimX, alloc->mHal.drvState.lod[0].dimY);
2232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
2242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsdGLCheckError(rsc, "AllocateRenderTarget");
225cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao#endif
2262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
2272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstatic void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
2292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
2302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
2312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsAssert(!alloc->mHal.state.type->getDimY());
2332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsAssert(!alloc->mHal.state.type->getDimZ());
2342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
2362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!drv->bufferID) {
2382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
2392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
2402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!drv->bufferID) {
241cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao        ALOGE("Upload to buffer object failed");
242cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao        drv->uploadDeferred = true;
243cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao        return;
244cf950c49a909350e529ddecffaae8be5429b9479Shih-wei Liao    }
24547aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines    RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
2462e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
247a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines                 alloc->mHal.drvState.lod[0].mallocPtr, GL_DYNAMIC_DRAW);
2489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
2492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsdGLCheckError(rsc, "UploadToBufferObject");
250cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet#endif
251c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet}
2522b8fb64be3047df940a219872b331eb11de2758dStephen Hines
253c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet
2542b8fb64be3047df940a219872b331eb11de2758dStephen Hinesstatic size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
255c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    // YUV only supports basic 2d
2562b8fb64be3047df940a219872b331eb11de2758dStephen Hines    // so we can stash the plane pointers in the mipmap levels.
257c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    size_t uvSize = 0;
258c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet#ifndef RS_SERVER
259c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    switch(yuv) {
260cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet    case HAL_PIXEL_FORMAT_YV12:
2612b8fb64be3047df940a219872b331eb11de2758dStephen Hines        state->lod[2].dimX = state->lod[0].dimX / 2;
2622b8fb64be3047df940a219872b331eb11de2758dStephen Hines        state->lod[2].dimY = state->lod[0].dimY / 2;
2639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
26492b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
26592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang                (state->lod[0].stride * state->lod[0].dimY);
26692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        uvSize += state->lod[2].stride * state->lod[2].dimY;
2672ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
2682ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        state->lod[1].dimX = state->lod[2].dimX;
2692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        state->lod[1].dimY = state->lod[2].dimY;
2702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        state->lod[1].stride = state->lod[2].stride;
2712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
2722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                (state->lod[2].stride * state->lod[2].dimY);
2732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        uvSize += state->lod[1].stride * state->lod[2].dimY;
2742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
27592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        state->lodCount = 3;
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        break;
27747aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines    case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
278462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        state->lod[1].dimX = state->lod[0].dimX;
27947aca4e016665d333fdcd01a9cef16c13d7836a8Stephen Hines        state->lod[1].dimY = state->lod[0].dimY / 2;
28048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        state->lod[1].stride = state->lod[0].stride;
28148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        state->lod[1].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                (state->lod[0].stride * state->lod[0].dimY);
28359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        uvSize += state->lod[1].stride * state->lod[1].dimY;
28459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        state->lodCount = 2;
28559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        break;
28659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    default:
28759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        rsAssert(0);
28859f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    }
28959f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet#endif
29059f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    return uvSize;
29159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet}
29259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
29359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
29459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouilletstatic size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
29559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        const Type *type, uint8_t *ptr) {
29659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    alloc->mHal.drvState.lod[0].dimX = type->getDimX();
29759f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    alloc->mHal.drvState.lod[0].dimY = type->getDimY();
298c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
299c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    alloc->mHal.drvState.lod[0].mallocPtr = 0;
300c643ceb752ed999def0fd028990eafa802cd13fbJean-Luc Brouillet    // Stride needs to be 16-byte aligned too!
30159f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    size_t stride = alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
30259f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    alloc->mHal.drvState.lod[0].stride = rsRound(stride, 16);
30359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    alloc->mHal.drvState.lodCount = type->getLODCount();
30459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    alloc->mHal.drvState.faceCount = type->getDimFaces();
30559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet
30659f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    size_t offsets[Allocation::MAX_LOD];
3073a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray    memset(offsets, 0, sizeof(offsets));
3083a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray
3093a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray    size_t o = alloc->mHal.drvState.lod[0].stride * rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
3103a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray            rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
3113a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray    if(alloc->mHal.drvState.lodCount > 1) {
3123a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray        uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
3133a38b7489d016b07e5b95a1e04ccfe9064b3438fTim Murray        uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
31459f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
31559f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet        for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
3162e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            alloc->mHal.drvState.lod[lod].dimX = tx;
317602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet            alloc->mHal.drvState.lod[lod].dimY = ty;
3182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            alloc->mHal.drvState.lod[lod].dimZ = tz;
3192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            alloc->mHal.drvState.lod[lod].stride =
3209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                    rsRound(tx * type->getElementSizeBytes(), 16);
3219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            offsets[lod] = o;
3222e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
3239ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (tx > 1) tx >>= 1;
3249ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (ty > 1) ty >>= 1;
3259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            if (tz > 1) tz >>= 1;
3262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
3272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else if (alloc->mHal.state.yuv) {
3282e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
3299ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3304a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines        for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
3314cc499d6e5ec602309501873449c938af61170b2Stephen Hines            offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
3324a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines        }
3334a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines    }
3344a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines
3354a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines    alloc->mHal.drvState.faceOffset = o;
3362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
3374a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines    alloc->mHal.drvState.lod[0].mallocPtr = ptr;
338593a894650e81be54173106ec266f0311cebebd3Stephen Hines    for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
3399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
3409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    size_t allocSize = alloc->mHal.drvState.faceOffset;
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if(alloc->mHal.drvState.faceCount) {
3442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        allocSize *= 6;
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return allocSize;
3489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
350462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaostatic uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero) {
3512e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    // We align all allocations to a 16-byte boundary.
3524c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    uint8_t* ptr = (uint8_t *)memalign(16, allocSize);
35359f22c376b2c1cd109735280689224fadfe40b42Jean-Luc Brouillet    if (!ptr) {
354d2936939ec10879e25746322db60071f79f28c1bStephen Hines        return NULL;
355f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
356f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (forceZero) {
357d2936939ec10879e25746322db60071f79f28c1bStephen Hines        memset(ptr, 0, allocSize);
358d2936939ec10879e25746322db60071f79f28c1bStephen Hines    }
359d2936939ec10879e25746322db60071f79f28c1bStephen Hines    return ptr;
360f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
3612e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
3622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletbool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
36344d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
3642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (!drv) {
3654c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines        return false;
366f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
367f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    alloc->mHal.drv = drv;
368f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
3699ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines    // Calculate the object size.
3704c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), NULL);
3714c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines
3724c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines    uint8_t * ptr = NULL;
373f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
374f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
375f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
376f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        // Allocation is allocated when the surface is created
377f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        // in getSurface
378f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else if (alloc->mHal.state.userProvidedPtr != NULL) {
379f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        // user-provided allocation
3802e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        // limitations: no faces, no LOD, USAGE_SCRIPT or SCRIPT+TEXTURE only
3814c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines        if (!(alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED) ||
3824c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines              alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))) {
3832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            ALOGE("Can't use user-allocated buffers if usage is not USAGE_SCRIPT | USAGE_SHARED or USAGE_SCRIPT | USAGE_SHARED | USAGE_GRAPHICS_TEXTURE");
3842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            return false;
3854c8b659edc8dca50ffb9c172258412fc1e02b80dStephen Hines        }
386f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
38744d495d2ad8c350a8f586502c9ee8e97a513646aStephen Hines            ALOGE("User-allocated buffers must not have multiple faces or LODs");
388b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams            return false;
389b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams        }
390b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams
391b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams        // rows must be 16-byte aligned
3922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        // validate that here, otherwise fall back to not use the user-backed allocation
3932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % 16) != 0) {
394b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams            ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
395d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            drv->useUserProvidedPtr = false;
3962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
397d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            ptr = allocAlignedMemory(allocSize, forceZero);
398d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            if (!ptr) {
399f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                alloc->mHal.drv = NULL;
400f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                free(drv);
401f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                return false;
402d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            }
403d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines
4042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        } else {
405d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            drv->useUserProvidedPtr = true;
406d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
407d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        }
408d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines    } else {
4092e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        ptr = allocAlignedMemory(allocSize, forceZero);
410d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        if (!ptr) {
411d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            alloc->mHal.drv = NULL;
412a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines            free(drv);
4132e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            return false;
414a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        }
4152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
416b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams    // Build the pointer tables
417b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams    size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr);
41848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    if(allocSize != verifySize) {
41948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        rsAssert(!"Size mismatch");
42048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
4212ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
42248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines#ifndef RS_SERVER
42348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    drv->glTarget = GL_NONE;
424c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
425c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        if (alloc->mHal.state.hasFaces) {
426c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            drv->glTarget = GL_TEXTURE_CUBE_MAP;
427c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        } else {
428c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            drv->glTarget = GL_TEXTURE_2D;
429c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        }
430c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    } else {
43148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
432c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            drv->glTarget = GL_ARRAY_BUFFER;
43348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        }
43448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
4352e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet#endif
43648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
43748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines#ifndef RS_COMPATIBILITY_LIB
43848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
4392e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
440b6902e2d07d1a0f20723f8502c65438a18d8b6e3Jason Sams#else
4412e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    drv->glType = 0;
4422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    drv->glFormat = 0;
4432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
444f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
44548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
44648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        drv->uploadDeferred = true;
4472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
4482e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
4492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
450f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    drv->readBackFBO = NULL;
4511f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
4529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // fill out the initial state of the buffer if we couldn't use the user-provided ptr and USAGE_SHARED was accepted
453462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if ((alloc->mHal.state.userProvidedPtr != 0) && (drv->useUserProvidedPtr == false)) {
4542e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        rsdAllocationData2D(rsc, alloc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, alloc->getType()->getDimX(), alloc->getType()->getDimY(), alloc->mHal.state.userProvidedPtr, allocSize, 0);
455602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet    }
4566e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines
4572ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    return true;
4582ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
459462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
460f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
461462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
462f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
463462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#ifndef RS_COMPATIBILITY_LIB
464462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if (drv->bufferID) {
4652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        // Causes a SW crash....
4662e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        //ALOGV(" mBufferID %i", mBufferID);
4672e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        //glDeleteBuffers(1, &mBufferID);
4685d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines        //mBufferID = 0;
4695d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    }
470f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (drv->textureID) {
471efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
472f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        drv->textureID = 0;
47348bac230fe966771f3074975fc2426ffde519edfShih-wei Liao    }
47448bac230fe966771f3074975fc2426ffde519edfShih-wei Liao    if (drv->renderTargetID) {
4752e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
476602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet        drv->renderTargetID = 0;
477602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet    }
4786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#endif
4799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
4809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (alloc->mHal.drvState.lod[0].mallocPtr) {
4812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        // don't free user-allocated ptrs or IO_OUTPUT buffers
4822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (!(drv->useUserProvidedPtr) &&
4832ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
4842ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
4852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                free(alloc->mHal.drvState.lod[0].mallocPtr);
4862ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
4872e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        alloc->mHal.drvState.lod[0].mallocPtr = NULL;
488324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
4892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
4902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
4912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (drv->readBackFBO != NULL) {
4922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        delete drv->readBackFBO;
4932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        drv->readBackFBO = NULL;
4942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
4952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
4962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
4972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
4982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
4992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
5002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        ANativeWindow *nw = drv->wndSurface;
5012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (nw) {
5022ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
5032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            mapper.unlock(drv->wndBuffer->handle);
5042e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
5052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
5069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
5079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#endif
5082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    free(drv);
5102ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    alloc->mHal.drv = NULL;
5112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
512f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
513f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationResize(const Context *rsc, const Allocation *alloc,
5142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                         const Type *newType, bool zeroNew) {
5152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const uint32_t oldDimX = alloc->mHal.drvState.lod[0].dimX;
5162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const uint32_t dimX = newType->getDimX();
5172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // can't resize Allocations with user-allocated buffers
5192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
5202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        ALOGE("Resize cannot be called on a USAGE_SHARED allocation");
5219ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return;
5229ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
523324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    void * oldPtr = alloc->mHal.drvState.lod[0].mallocPtr;
5242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Calculate the object size
5252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    size_t s = AllocationBuildPointerTable(rsc, alloc, newType, NULL);
5262ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    uint8_t *ptr = (uint8_t *)realloc(oldPtr, s);
5272ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    // Build the relative pointer tables.
5282ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    size_t verifySize = AllocationBuildPointerTable(rsc, alloc, newType, ptr);
5292ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if(s != verifySize) {
5302ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        rsAssert(!"Size mismatch");
5312ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
5322ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5332ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5342ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (dimX > oldDimX) {
5352ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        size_t stride = alloc->mHal.state.elementSizeBytes;
5362ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        memset(((uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr) + stride * oldDimX,
5372ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                 0, stride * (dimX - oldDimX));
5382ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
5392ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
5402ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5412ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouilletstatic void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
5422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
5432ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!alloc->getIsScript()) {
5449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return; // nothing to sync
5459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
5466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
5476315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
548462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
5496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines
5506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
551462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    if (!drv->textureID && !drv->renderTargetID) {
552f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        return; // nothing was rendered here yet, so nothing to sync
553a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
5542968921e1cedf85360964c5a39e1ce36c66ecd09Jean-Luc Brouillet    if (drv->readBackFBO == NULL) {
555462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        drv->readBackFBO = new RsdFrameBufferObj();
5569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        drv->readBackFBO->setColorTarget(drv, 0);
5579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
5589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                        alloc->getType()->getDimY());
5599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
5609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Bind the framebuffer object so we can read back from it
562462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    drv->readBackFBO->setActive(rsc);
5639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Do the readback
565462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    RSD_CALL_GL(glReadPixels, 0, 0, alloc->mHal.drvState.lod[0].dimX,
566f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                alloc->mHal.drvState.lod[0].dimY,
5679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                drv->glFormat, drv->glType, alloc->mHal.drvState.lod[0].mallocPtr);
5689ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
5699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    // Revert framebuffer to its original
5702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    lastFbo->setActive(rsc);
5712ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
5722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
5732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5742ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaovoid rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
576462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                         RsAllocationUsageType src) {
577462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
5782e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
5799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
580462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        if(!alloc->getIsRenderTarget()) {
581f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            rsc->setError(RS_ERROR_FATAL_DRIVER,
582f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                          "Attempting to sync allocation from render target, "
583462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                          "for non-render target allocation");
5849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
5852ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
5862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                                 "render target");
5872ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        } else {
5882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            rsdAllocationSyncFromFBO(rsc, alloc);
5892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
5902e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        return;
5912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
5922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
5932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
5942e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
5952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
5962ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        UploadToTexture(rsc, alloc);
5972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
5982e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
5992ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
6002ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            AllocateRenderTarget(rsc, alloc);
6012ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
6022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
6032ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
6042ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        UploadToBufferObject(rsc, alloc);
6052ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
6062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
6072ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
6082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        // NOP in CPU driver for now
6092ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    }
6109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
611462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    drv->uploadDeferred = false;
612462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
6132e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
614f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
615f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
6169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    drv->uploadDeferred = true;
6179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
6182e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
6199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#ifndef RS_COMPATIBILITY_LIB
6200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Changvoid DrvAllocation::NewBufferListener::onFrameAvailable() {
6210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    intptr_t ip = (intptr_t)alloc;
6222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, ip, 0, true);
6232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
6242ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet#endif
6252ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
6260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Changvoid* rsdAllocationGetSurface(const Context *rsc, const Allocation *alloc) {
6279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#ifndef RS_COMPATIBILITY_LIB
6289ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
6292e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
6302e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    // Configure CpuConsumer to be in asynchronous mode
6312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    drv->cpuConsumer = new CpuConsumer(2, false);
6322e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    sp<IGraphicBufferProducer> bp = drv->cpuConsumer->getProducerInterface();
6332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    bp->incStrong(NULL);
6349ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
6359ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    drv->mBufferListener = new DrvAllocation::NewBufferListener();
636f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    drv->mBufferListener->rsc = rsc;
637f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    drv->mBufferListener->alloc = alloc;
6389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
6399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    drv->cpuConsumer->setFrameAvailableListener(drv->mBufferListener);
6409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
6419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    return bp.get();
6422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet#else
6432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    return NULL;
6449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#endif
645f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
646f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
6479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#ifndef RS_COMPATIBILITY_LIB
6489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaostatic bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
6492e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
6509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
651462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
652c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (r) {
653c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
654c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        return false;
655c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
656c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
657c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    // Must lock the whole surface
658c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
659c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
660c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
661c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    void *dst = NULL;
662c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    mapper.lock(drv->wndBuffer->handle,
663c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
664c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            bounds, &dst);
665c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    alloc->mHal.drvState.lod[0].mallocPtr = dst;
666c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
667c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    rsAssert((alloc->mHal.drvState.lod[0].stride & 0xf) == 0);
668c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
669c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    return true;
6702e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet}
671c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines#endif
672c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
673c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hinesvoid rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
674f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet#ifndef RS_COMPATIBILITY_LIB
675f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
676f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    ANativeWindow *old = drv->wndSurface;
677c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines
678c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines    if (nw) {
679c17e198ffcd37bfc57e3add1f6eee952ae2a2eabStephen Hines        nw->incStrong(NULL);
680f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
681f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
682f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
683593a894650e81be54173106ec266f0311cebebd3Stephen Hines        //TODO finish support for render target + script
684b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        drv->wnd = nw;
6852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        return;
686593a894650e81be54173106ec266f0311cebebd3Stephen Hines    }
6879ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines
688593a894650e81be54173106ec266f0311cebebd3Stephen Hines    // Cleanup old surface if there is one.
689c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (drv->wndSurface) {
690c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        ANativeWindow *old = drv->wndSurface;
691c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        GraphicBufferMapper &mapper = GraphicBufferMapper::get();
692c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        mapper.unlock(drv->wndBuffer->handle);
693c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        old->cancelBuffer(old, drv->wndBuffer, -1);
694b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        drv->wndSurface = NULL;
695c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        old->decStrong(NULL);
696c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
697c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
698c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (nw != NULL) {
699c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        int32_t r;
700c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        uint32_t flags = 0;
701c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
702c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
703c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
704c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        }
7059ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
706593a894650e81be54173106ec266f0311cebebd3Stephen Hines            flags |= GRALLOC_USAGE_HW_RENDER;
707b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        }
708b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
709b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        r = native_window_set_usage(nw, flags);
710b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        if (r) {
7112ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
7122ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            goto error;
7132ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
7142ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
715593a894650e81be54173106ec266f0311cebebd3Stephen Hines        r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
716593a894650e81be54173106ec266f0311cebebd3Stephen Hines                                                 alloc->mHal.drvState.lod[0].dimY);
717593a894650e81be54173106ec266f0311cebebd3Stephen Hines        if (r) {
718b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
7192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            goto error;
7202e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        }
721b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
7222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        int format = 0;
723f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        const Element *e = alloc->mHal.state.type->getElement();
724c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        switch(e->getType()) {
725c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        case RS_TYPE_UNSIGNED_8:
726b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray            switch (e->getVectorSize()) {
7272e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            case 1:
728b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray                rsAssert(e->getKind() == RS_KIND_PIXEL_A);
729b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray                format = PIXEL_FORMAT_A_8;
73050974740c0c5c52dd766264139a01702fbc138afStephen Hines                break;
7312e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            case 4:
73250974740c0c5c52dd766264139a01702fbc138afStephen Hines                rsAssert(e->getKind() == RS_KIND_PIXEL_RGBA);
733f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                format = PIXEL_FORMAT_RGBA_8888;
734f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                break;
73550974740c0c5c52dd766264139a01702fbc138afStephen Hines            default:
736c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                rsAssert(0);
737f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            }
738c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            break;
739c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        default:
740c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            rsAssert(0);
741c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        }
742c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
743c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        r = native_window_set_buffers_format(nw, format);
744c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        if (r) {
74550974740c0c5c52dd766264139a01702fbc138afStephen Hines            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
74650974740c0c5c52dd766264139a01702fbc138afStephen Hines            goto error;
74750974740c0c5c52dd766264139a01702fbc138afStephen Hines        }
748f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
74950974740c0c5c52dd766264139a01702fbc138afStephen Hines        IoGetBuffer(rsc, alloc, nw);
75050974740c0c5c52dd766264139a01702fbc138afStephen Hines        drv->wndSurface = nw;
75150974740c0c5c52dd766264139a01702fbc138afStephen Hines    }
752f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
75350974740c0c5c52dd766264139a01702fbc138afStephen Hines    return;
75450974740c0c5c52dd766264139a01702fbc138afStephen Hines
75550974740c0c5c52dd766264139a01702fbc138afStephen Hines error:
756f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
75750974740c0c5c52dd766264139a01702fbc138afStephen Hines    if (nw) {
7582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        nw->decStrong(NULL);
75950974740c0c5c52dd766264139a01702fbc138afStephen Hines    }
76050974740c0c5c52dd766264139a01702fbc138afStephen Hines
76150974740c0c5c52dd766264139a01702fbc138afStephen Hines
76250974740c0c5c52dd766264139a01702fbc138afStephen Hines#endif
76350974740c0c5c52dd766264139a01702fbc138afStephen Hines}
7642e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
765593a894650e81be54173106ec266f0311cebebd3Stephen Hinesvoid rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
766c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes#ifndef RS_COMPATIBILITY_LIB
767c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
768c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    ANativeWindow *nw = drv->wndSurface;
769c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
770c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        RsdHal *dc = (RsdHal *)rsc->mHal.drv;
771c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
772c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        return;
773c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
774c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (nw) {
775c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
776c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
777c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            mapper.unlock(drv->wndBuffer->handle);
778c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
779c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            if (r) {
780b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines                rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
781c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes                return;
782b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            }
7832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
784593a894650e81be54173106ec266f0311cebebd3Stephen Hines            IoGetBuffer(rsc, alloc, nw);
785593a894650e81be54173106ec266f0311cebebd3Stephen Hines        }
786c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    } else {
787c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        rsc->setError(RS_ERROR_DRIVER, "Sent IO buffer with no attached surface.");
788c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        return;
789c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
790c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes#endif
791c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes}
792c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
793c9454afec1649846512993d0ef65a9f868976bb4Chris Wailesvoid rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
794c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes#ifndef RS_COMPATIBILITY_LIB
795c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
796c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
797c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
798c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        CpuConsumer::LockedBuffer lb;
799c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        status_t ret = drv->cpuConsumer->lockNextBuffer(&lb);
800c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        if (ret == OK) {
801c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            if (drv->lb.data != NULL) {
802593a894650e81be54173106ec266f0311cebebd3Stephen Hines                drv->cpuConsumer->unlockBuffer(drv->lb);
803593a894650e81be54173106ec266f0311cebebd3Stephen Hines            }
804b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            drv->lb = lb;
805b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            alloc->mHal.drvState.lod[0].mallocPtr = drv->lb.data;
8062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            alloc->mHal.drvState.lod[0].stride = drv->lb.stride *
8072e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                    alloc->mHal.state.elementSizeBytes;
808b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
809b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines            if (alloc->mHal.state.yuv) {
810f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
811f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            }
812b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        } else if (ret == BAD_VALUE) {
813c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            // No new frame, don't do anything
814f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        } else {
815c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes            rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
816c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        }
817c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
818c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    } else {
819c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes        drv->surfaceTexture->updateTexImage();
820c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes    }
821c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
822c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
823c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes#endif
824c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes}
825c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
826c9454afec1649846512993d0ef65a9f868976bb4Chris Wailes
827b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hinesvoid rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
8289ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                         uint32_t xoff, uint32_t lod, size_t count,
829f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                         const void *data, size_t sizeBytes) {
830b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
831f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
832b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
833b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
834f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    size_t size = count * eSize;
835b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines
836f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (ptr != data) {
837b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        // Skip the copy if we are the same allocation. This can arise from
83850974740c0c5c52dd766264139a01702fbc138afStephen Hines        // our Bitmap optimization, where we share the same storage.
839f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        if (alloc->mHal.state.hasReferences) {
84050974740c0c5c52dd766264139a01702fbc138afStephen Hines            alloc->incRefs(data, count);
841f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            alloc->decRefs(ptr, count);
84250974740c0c5c52dd766264139a01702fbc138afStephen Hines        }
843b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        memcpy(ptr, data, size);
8442e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
845593a894650e81be54173106ec266f0311cebebd3Stephen Hines    drv->uploadDeferred = true;
846593a894650e81be54173106ec266f0311cebebd3Stephen Hines}
8472e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
84848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hinesvoid rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
8499ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines                         uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
85048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                         uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
8512ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
8522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
8539ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    size_t eSize = alloc->mHal.state.elementSizeBytes;
8549ca96e70657cf5437a294213f56ba4768dc08ad2Stephen Hines    size_t lineSize = eSize * w;
8552e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (!stride) {
856a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        stride = lineSize;
857a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines    }
85848b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
8592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (alloc->mHal.drvState.lod[0].mallocPtr) {
860a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        const uint8_t *src = static_cast<const uint8_t *>(data);
8612ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
8622ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (dst == src) {
8632ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            // Skip the copy if we are the same allocation. This can arise from
8642ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            // our Bitmap optimization, where we share the same storage.
8652e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            drv->uploadDeferred = true;
866f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            return;
867f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        }
868a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines
8692ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        for (uint32_t line=yoff; line < (yoff+h); line++) {
8702ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            if (alloc->mHal.state.hasReferences) {
87148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                alloc->incRefs(src, w);
8722ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                alloc->decRefs(dst, w);
8732ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            }
8742e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            memcpy(dst, src, lineSize);
875f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            src += stride;
876f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            dst += alloc->mHal.drvState.lod[lod].stride;
87748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        }
8782ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        if (alloc->mHal.state.yuv) {
8792ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            int lod = 1;
880a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines            while (alloc->mHal.drvState.lod[lod].mallocPtr) {
8812ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                size_t lineSize = alloc->mHal.drvState.lod[lod].dimX;
8822ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
88348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
88448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                for (uint32_t line=(yoff >> 1); line < ((yoff+h)>>1); line++) {
88548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                    memcpy(dst, src, lineSize);
8862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                    src += lineSize;
8871f6c331d622ac645ab68a016aa4c577998547373Stephen Hines                    dst += alloc->mHal.drvState.lod[lod].stride;
8882ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                }
8892ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                lod++;
8902ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            }
8912ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
8922ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        }
8932e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        drv->uploadDeferred = true;
8942ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    } else {
8952ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet        Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
8961f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    }
8972ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet}
8982ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
8991f6c331d622ac645ab68a016aa4c577998547373Stephen Hinesvoid rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
9001f6c331d622ac645ab68a016aa4c577998547373Stephen Hines                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
9011f6c331d622ac645ab68a016aa4c577998547373Stephen Hines                         uint32_t lod,
9022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                         uint32_t w, uint32_t h, uint32_t d, const void *data,
903602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                         size_t sizeBytes, size_t stride) {
904f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
90548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
90648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
90748b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    uint32_t lineSize = eSize * w;
9082ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    if (!stride) {
90948b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        stride = lineSize;
91048b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    }
91148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines
91248b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines    if (alloc->mHal.drvState.lod[0].mallocPtr) {
91348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        const uint8_t *src = static_cast<const uint8_t *>(data);
91448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        for (uint32_t z = zoff; z < d; z++) {
9152ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
9162ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                        RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
9172ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            if (dst == src) {
9182ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                // Skip the copy if we are the same allocation. This can arise from
9192ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                // our Bitmap optimization, where we share the same storage.
9202ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                drv->uploadDeferred = true;
92148b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                return;
9222ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet            }
9232ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet
92448b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines            for (uint32_t line=yoff; line < (yoff+h); line++) {
92548b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                if (alloc->mHal.state.hasReferences) {
92648b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines                    alloc->incRefs(src, w);
927f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                    alloc->decRefs(dst, w);
928f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                }
929f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                memcpy(dst, src, lineSize);
930f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                src += stride;
931f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                dst += alloc->mHal.drvState.lod[lod].stride;
932f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            }
93348b72bf3ea4a7dc66a0b59734aeb0c4adfb4d9d1Stephen Hines        }
934b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines        drv->uploadDeferred = true;
935b5a89fbfcba6d8817c1c3700ed78bd6482cf1a5dStephen Hines    }
9362e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet}
937602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet
938602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid rsdAllocationRead1D(const Context *rsc, const Allocation *alloc,
939602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                         uint32_t xoff, uint32_t lod, size_t count,
9409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         void *data, size_t sizeBytes) {
9419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
9422ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet    const uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
9430d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    if (data != ptr) {
9440d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines        // Skip the copy if we are the same allocation. This can arise from
9459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        // our Bitmap optimization, where we share the same storage.
9462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        memcpy(data, ptr, count * eSize);
9479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
9485d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines}
949f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
950f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationRead2D(const Context *rsc, const Allocation *alloc,
9515d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines                                uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
952efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
953f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    size_t eSize = alloc->mHal.state.elementSizeBytes;
9545d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    size_t lineSize = eSize * w;
9555d67178077b50d0a02832e91053ee71ec33a25c2Stephen Hines    if (!stride) {
9561f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        stride = lineSize;
9571f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    }
9582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
9592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (alloc->mHal.drvState.lod[0].mallocPtr) {
960bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines        uint8_t *dst = static_cast<uint8_t *>(data);
9611f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
9621f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        if (dst == src) {
9631f6c331d622ac645ab68a016aa4c577998547373Stephen Hines            // Skip the copy if we are the same allocation. This can arise from
964bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines            // our Bitmap optimization, where we share the same storage.
965bcae1fe692a8c5d9225a9699a932380b5659a735Stephen Hines            return;
9661f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        }
9671f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
9681f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        for (uint32_t line=yoff; line < (yoff+h); line++) {
969f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            memcpy(dst, src, lineSize);
970f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            dst += stride;
971f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            src += alloc->mHal.drvState.lod[lod].stride;
972f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        }
973f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    } else {
974f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        ALOGE("Add code to readback from non-script memory");
975f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
976f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
977f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
978f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
9792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid rsdAllocationRead3D(const Context *rsc, const Allocation *alloc,
9802e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
981f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                         uint32_t lod,
982f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                         uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
9831f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
984f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    uint32_t lineSize = eSize * w;
985f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    if (!stride) {
9861f6c331d622ac645ab68a016aa4c577998547373Stephen Hines        stride = lineSize;
9879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
9881f6c331d622ac645ab68a016aa4c577998547373Stephen Hines
9891f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    if (alloc->mHal.drvState.lod[0].mallocPtr) {
990f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        uint8_t *dst = static_cast<uint8_t *>(data);
991462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for (uint32_t z = zoff; z < d; z++) {
9922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
9939ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                              RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
994462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            if (dst == src) {
9952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                // Skip the copy if we are the same allocation. This can arise from
9962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                // our Bitmap optimization, where we share the same storage.
997462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                return;
998462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            }
999efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1000efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet            for (uint32_t line=yoff; line < (yoff+h); line++) {
1001efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                memcpy(dst, src, lineSize);
1002efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                dst += stride;
1003efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                src += alloc->mHal.drvState.lod[lod].stride;
1004f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            }
1005efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        }
1006efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    }
1007f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
1008efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1009f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid * rsdAllocationLock1D(const android::renderscript::Context *rsc,
1010efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                          const android::renderscript::Allocation *alloc) {
1011efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    return alloc->mHal.drvState.lod[0].mallocPtr;
1012efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
1013efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1014efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletvoid rsdAllocationUnlock1D(const android::renderscript::Context *rsc,
1015efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                          const android::renderscript::Allocation *alloc) {
1016efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1017efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet}
1018efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1019f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
1020efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                               const android::renderscript::Allocation *dstAlloc,
1021efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                               uint32_t dstXoff, uint32_t dstLod, size_t count,
1022f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                               const android::renderscript::Allocation *srcAlloc,
1023efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                               uint32_t srcXoff, uint32_t srcLod) {
1024f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
1025efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1026efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1027efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouilletvoid rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
1028efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      const android::renderscript::Allocation *dstAlloc,
1029efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1030efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1031efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      const android::renderscript::Allocation *srcAlloc,
1032efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1033efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet                                      RsAllocationCubemapFace srcFace) {
1034efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
1035efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet    for (uint32_t i = 0; i < h; i ++) {
1036efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
1037efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
1038efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        memcpy(dstPtr, srcPtr, w * elementSize);
1039efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet
1040efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
1041efcff1017f5f1e120a8ffb67125e412343479f94Jean-Luc Brouillet        //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
10422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
10439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
10449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
1045462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liaovoid rsdAllocationData3D_alloc_script(const android::renderscript::Context *rsc,
10466e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                                      const android::renderscript::Allocation *dstAlloc,
10476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod,
1048462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                      uint32_t w, uint32_t h, uint32_t d,
10492ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                      const android::renderscript::Allocation *srcAlloc,
10500d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod) {
10510d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
1052462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    for (uint32_t j = 0; j < d; j++) {
10532e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        for (uint32_t i = 0; i < h; i ++) {
1054462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j,
105589273bd59a182fc0401d68f14ad206bf4dc800c7Zonr Chang                                           dstLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
10562e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j,
10572e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                           srcLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1058462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            memcpy(dstPtr, srcPtr, w * elementSize);
1059f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
1060f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
1061f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
1062462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        }
1063f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
1064f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
1065f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
1066f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouilletvoid rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
1067f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                               const android::renderscript::Allocation *dstAlloc,
1068f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
1069f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                               RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
1070462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                               const android::renderscript::Allocation *srcAlloc,
10712e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
1072462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                               RsAllocationCubemapFace srcFace) {
10732e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
1074462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
1075462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                                             "yet implemented.");
10762e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        return;
10776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    }
10786e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
10799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                                     dstLod, dstFace, w, h, srcAlloc,
10800d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines                                     srcXoff, srcYoff, srcLod, srcFace);
10810d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
10829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
10832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
10842e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                               const android::renderscript::Allocation *dstAlloc,
10852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
10862e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                               uint32_t dstLod,
1087462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                               uint32_t w, uint32_t h, uint32_t d,
1088462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao                               const android::renderscript::Allocation *srcAlloc,
10892e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
10906e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines                               uint32_t srcLod) {
10916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
109292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
10932ce118e843fcbd53488b503933136bb4fdbdfbc1Jean-Luc Brouillet                                             "yet implemented.");
10940d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines        return;
10950d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    }
109692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    rsdAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
10972e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                     dstLod, w, h, d, srcAlloc,
109892b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang                                     srcXoff, srcYoff, srcZoff, srcLod);
109992b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang}
110092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
11010d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hinesvoid rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
11022e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                uint32_t x,
11032e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                                const void *data, uint32_t cIdx, size_t sizeBytes) {
1104f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
110592b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
11062e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    size_t eSize = alloc->mHal.state.elementSizeBytes;
11072e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    uint8_t * ptr = GetOffsetPtr(alloc, x, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
1108f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
1109f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
111092b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
11112e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
111292b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    if (alloc->mHal.state.hasReferences) {
111392b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang        e->incRefs(data);
11142e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        e->decRefs(ptr);
11152e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
111692b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang
111792b344a51c6c4934e96882bd401e4b13d6d03db8Zonr Chang    memcpy(ptr, data, sizeBytes);
1118602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet    drv->uploadDeferred = true;
11192e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet}
1120602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet
1121602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouilletvoid rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
1122602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                                uint32_t x, uint32_t y,
11232e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang                                const void *data, uint32_t cIdx, size_t sizeBytes) {
11240d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
11250d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines
11262e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    size_t eSize = alloc->mHal.state.elementSizeBytes;
11272e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    uint8_t * ptr = GetOffsetPtr(alloc, x, y, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
11282e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
11292e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
11302e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
11312e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang
11322e1dba6c779a0ae55c76d36a3c03553e16725ab7Zonr Chang    if (alloc->mHal.state.hasReferences) {
11332e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        e->incRefs(data);
11346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        e->decRefs(ptr);
11356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    }
11369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
11370d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    memcpy(ptr, data, sizeBytes);
11380d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    drv->uploadDeferred = true;
11399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
11402e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
11412e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletstatic void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
11422e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
11432e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
11440d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines
11450d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    for (uint32_t y=0; y < h; y++) {
11462e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1147602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet        const uint16_t *i1 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2, lod, face);
1148f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        const uint16_t *i2 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2+1, lod, face);
1149f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
11500d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines        for (uint32_t x=0; x < w; x++) {
11519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
11522e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            oPtr ++;
1153602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet            i1 += 2;
11549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            i2 += 2;
11550d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines        }
11560d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines    }
11570d26cef64debfaa6862a27587c1fd0d30baa3b1dStephen Hines}
11582e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
11592e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletstatic void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
1160f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
11619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
11622e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
11632e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    for (uint32_t y=0; y < h; y++) {
1164a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
1165a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        const uint32_t *i1 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1166a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines        const uint32_t *i2 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
1167f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
1168f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        for (uint32_t x=0; x < w; x++) {
1169a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
1170a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines            oPtr ++;
1171a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hines            i1 += 2;
1172f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            i2 += 2;
1173f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet        }
1174f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
1175f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet}
1176f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet
1177a6b54146b93eec68f6daa4b1877639cdc34801dcStephen Hinesstatic void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
11781ebc0ca6ffa7effb875883d18205ed4943ab8fc2Shih-wei Liao    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
11792e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
11809ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
11819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    for (uint32_t y=0; y < h; y++) {
1182462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
11832e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        const uint8_t *i1 = GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
1184602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet        const uint8_t *i2 = GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);
11852e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet
1186462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for (uint32_t x=0; x < w; x++) {
1187f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
1188462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao            oPtr ++;
11892e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet            i1 += 2;
119028d60bc2da19821af82d983902c3c78c078343c3Stephen Hines            i2 += 2;
119128d60bc2da19821af82d983902c3c78c078343c3Stephen Hines        }
11922e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    }
119328d60bc2da19821af82d983902c3c78c078343c3Stephen Hines}
1194b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray
11952e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouilletvoid rsdAllocationGenerateMipmaps(const Context *rsc, const Allocation *alloc) {
11962e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet    if(!alloc->mHal.drvState.lod[0].mallocPtr) {
1197b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray        return;
1198f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    }
1199f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet    uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
1200b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray    for (uint32_t face = 0; face < numFaces; face ++) {
12012e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet        for (uint32_t lod=0; lod < (alloc->getType()->getLODCount() -1); lod++) {
1202b81a993cc0fed2dabfb1abc8b23ab9bd1586f201Tim Murray            switch (alloc->getType()->getElement()->getSizeBits()) {
12039c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao            case 32:
12049c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao                mip8888(alloc, lod, (RsAllocationCubemapFace)face);
12059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                break;
12069ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            case 16:
12072e205d071c86981a8dd301a8612d17b251b3b973Jean-Luc Brouillet                mip565(alloc, lod, (RsAllocationCubemapFace)face);
1208602def74e8afa68b72a1f9391c31d6ff152add53Jean-Luc Brouillet                break;
1209c95381a2c3b6e9117901eef0687e861e4d533bfeJean-Luc Brouillet            case 8:
12109ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                mip8(alloc, lod, (RsAllocationCubemapFace)face);
1211f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet                break;
1212f33e1561dc390cf2be7a81e9f818b269d458ec7eJean-Luc Brouillet            }
12139ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        }
12149ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
12159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}
12169c631ff2e65a8fa766981c9683c3b255ce0a2388Shih-wei Liao