SoftwareRenderer.cpp revision ba529e486dde15fe75ea1b48570f9d60a4cf3c48
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SoftwareRenderer"
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2089e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "../include/SoftwareRenderer.h"
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <binder/MemoryHeapBase.h>
2389e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber#include <binder/MemoryHeapPmem.h>
240c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h>
255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h>
265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/android_native_buffer.h>
275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
293e135cf939b4baf9902fe24fb0e50528e62c10bdJamie Gennis// XXX: Temporary hack to allow referencing the _ADRENO pixel format here.
303e135cf939b4baf9902fe24fb0e50528e62c10bdJamie Gennis#include <libgralloc-qsd8k/gralloc_priv.h>
313e135cf939b4baf9902fe24fb0e50528e62c10bdJamie Gennis
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::SoftwareRenderer(
3510f75b8c71beb7f327e50bbac8e528af4e40fa24Andreas Huber        OMX_COLOR_FORMATTYPE colorFormat,
365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const sp<Surface> &surface,
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t displayWidth, size_t displayHeight,
38ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        size_t decodedWidth, size_t decodedHeight,
39ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        int32_t rotationDegrees)
4010f75b8c71beb7f327e50bbac8e528af4e40fa24Andreas Huber    : mColorFormat(colorFormat),
415daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mConverter(NULL),
425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mSurface(surface),
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDisplayWidth(displayWidth),
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDisplayHeight(displayHeight),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDecodedWidth(decodedWidth),
475daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mDecodedHeight(decodedHeight) {
485daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    LOGI("input format = %d", mColorFormat);
495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    LOGI("display = %d x %d, decoded = %d x %d",
505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mDisplayWidth, mDisplayHeight, mDecodedWidth, mDecodedHeight);
515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
52a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber    mDecodedWidth = mDisplayWidth;
53a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber    mDecodedHeight = mDisplayHeight;
54a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber
555daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    int halFormat;
565daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    switch (mColorFormat) {
575daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#if HAS_YCBCR420_SP_ADRENO
585daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        case OMX_COLOR_FormatYUV420Planar:
595daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        {
605daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO;
615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mYUVMode = YUV420ToYUV420sp;
625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
635daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
655daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        case 0x7fa30c00:
665daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        {
675daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO;
685daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mYUVMode = YUV420spToYUV420sp;
695daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
705daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
715daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#endif
725daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
735daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        default:
745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_RGB_565;
755daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
765daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mConverter = new ColorConverter(
775daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    mColorFormat, OMX_COLOR_Format16bitRGB565);
785daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            CHECK(mConverter->isValid());
795daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
8089e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
8189e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mSurface.get() != NULL);
830c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mDecodedWidth > 0);
840c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mDecodedHeight > 0);
855daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
865daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
875daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
885daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mSurface.get(),
905daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
915daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            | GRALLOC_USAGE_HW_TEXTURE));
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
935daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffer_count(mSurface.get(), 2));
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
955daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffers_geometry(
975daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                mSurface.get(), mDecodedWidth, mDecodedHeight,
985daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
99ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
100ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
101ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
102ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
103ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
104ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
105ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
106ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
107ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
108ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
109ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (transform) {
110ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ(0, native_window_set_buffers_transform(
111ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                    mSurface.get(), transform));
112ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() {
1165daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    delete mConverter;
1175daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mConverter = NULL;
1185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
1195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1205daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huberstatic inline size_t ALIGN(size_t x, size_t alignment) {
1215daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    return (x + alignment - 1) & ~(alignment - 1);
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const void *data, size_t size, void *platformPrivate) {
1265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    android_native_buffer_t *buf;
1275de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1285de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    if ((err = mSurface->dequeueBuffer(mSurface.get(), &buf)) != 0) {
1295de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::dequeueBuffer returned error %d", err);
1305de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1315de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1325de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1335daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), buf));
1345daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1355daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1375daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    Rect bounds(mDecodedWidth, mDecodedHeight);
1385daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
1405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
1415daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1425daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
1445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
1455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                mDecodedWidth, mDecodedHeight,
1465daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                data, 0, dst, buf->stride * 2);
1475daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    } else if (mYUVMode == YUV420spToYUV420sp) {
1485daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        // Input and output are both YUV420sp, but the alignment requirements
1495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        // are different.
1505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t srcYStride = mDecodedWidth;
1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const uint8_t *srcY = (const uint8_t *)data;
1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        uint8_t *dstY = (uint8_t *)dst;
1535daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        for (size_t i = 0; i < mDecodedHeight; ++i) {
1545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            memcpy(dstY, srcY, mDecodedWidth);
1555daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcY += srcYStride;
1565daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            dstY += buf->stride;
1575daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
1585daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1595daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t srcUVStride = (mDecodedWidth + 1) & ~1;
1605daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t dstUVStride = ALIGN(mDecodedWidth / 2, 32) * 2;
1615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const uint8_t *srcUV = (const uint8_t *)data
1635daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            + mDecodedHeight * mDecodedWidth;
1645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1655daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t dstUVOffset = ALIGN(ALIGN(mDecodedHeight, 32) * buf->stride, 4096);
1665daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        uint8_t *dstUV = (uint8_t *)dst + dstUVOffset;
1675daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1685daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        for (size_t i = 0; i < (mDecodedHeight + 1) / 2; ++i) {
1695daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            memcpy(dstUV, srcUV, (mDecodedWidth + 1) & ~1);
1705daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcUV += srcUVStride;
1715daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            dstUV += dstUVStride;
1725daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
1735daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    } else if (mYUVMode == YUV420ToYUV420sp) {
1745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        // Input is YUV420 planar, output is YUV420sp, adhere to proper
1755daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        // alignment requirements.
1765daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t srcYStride = mDecodedWidth;
1775daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const uint8_t *srcY = (const uint8_t *)data;
1785daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        uint8_t *dstY = (uint8_t *)dst;
1795daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        for (size_t i = 0; i < mDecodedHeight; ++i) {
1805daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            memcpy(dstY, srcY, mDecodedWidth);
1815daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcY += srcYStride;
1825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            dstY += buf->stride;
1835daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
1845daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1855daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t srcUVStride = (mDecodedWidth + 1) / 2;
1865daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t dstUVStride = ALIGN(mDecodedWidth / 2, 32) * 2;
1875daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1885daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const uint8_t *srcU = (const uint8_t *)data
1895daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            + mDecodedHeight * mDecodedWidth;
1905daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1915daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        const uint8_t *srcV =
1925daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcU + ((mDecodedWidth + 1) / 2) * ((mDecodedHeight + 1) / 2);
1935daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1945daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        size_t dstUVOffset = ALIGN(ALIGN(mDecodedHeight, 32) * buf->stride, 4096);
1955daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        uint8_t *dstUV = (uint8_t *)dst + dstUVOffset;
1965daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1975daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        for (size_t i = 0; i < (mDecodedHeight + 1) / 2; ++i) {
1985daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            for (size_t j = 0; j < (mDecodedWidth + 1) / 2; ++j) {
1995daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                dstUV[2 * j + 1] = srcU[j];
2005daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                dstUV[2 * j] = srcV[j];
2015daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            }
2025daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcU += srcUVStride;
2035daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            srcV += srcUVStride;
2045daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            dstUV += dstUVStride;
2055daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        }
2065daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    } else {
2075daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        memcpy(dst, data, size);
2085daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
2094265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2105daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
2114265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
2125de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    if ((err = mSurface->queueBuffer(mSurface.get(), buf)) != 0) {
2135de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::queueBuffer returned error %d", err);
2145de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2155daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
2164265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
2174265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
219