SoftwareRenderer.cpp revision 760f92f8b6da9c9cf128cb18fe3c09402fdde6cd
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
229dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber#include <cutils/properties.h> // for property_get
23f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu#include <media/stagefright/foundation/AMessage.h>
259eeafeb52fecf90882e9b44eeefcb7c3e16aa915Mathias Agopian#include <system/window.h>
265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h>
278ba01021b573889802e67e029225a96f0dfa471aAndy McFadden#include <gui/IGraphicBufferProducer.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
319dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huberstatic bool runningInEmulator() {
329dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber    char prop[PROPERTY_VALUE_MAX];
339dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber    return (property_get("ro.kernel.qemu", prop, NULL) > 0);
349dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber}
359dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber
36475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wustatic int ALIGN(int x, int y) {
37475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    // y must be a power of 2.
38475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    return (x + y - 1) & ~(y - 1);
39475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
40475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
41475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::SoftwareRenderer(const sp<ANativeWindow> &nativeWindow)
42475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    : mColorFormat(OMX_COLOR_FormatUnused),
43475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mConverter(NULL),
445daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
45475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mNativeWindow(nativeWindow),
46475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mWidth(0),
47475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mHeight(0),
48475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropLeft(0),
49475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropTop(0),
50475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropRight(0),
51475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropBottom(0),
52475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropWidth(0),
53475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropHeight(0) {
54475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
55475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
56475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::~SoftwareRenderer() {
57475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    delete mConverter;
58475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mConverter = NULL;
59475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
60475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
61475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wuvoid SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) {
62475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format != NULL);
63475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
64475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t colorFormatNew;
65475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format->findInt32("color-format", &colorFormatNew));
66475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
67475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t widthNew, heightNew;
68a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu    CHECK(format->findInt32("stride", &widthNew));
69a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu    CHECK(format->findInt32("slice-height", &heightNew));
70475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
71475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
72475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findRect(
73475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            "crop", &cropLeftNew, &cropTopNew, &cropRightNew, &cropBottomNew)) {
74475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropLeftNew = cropTopNew = 0;
75475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropRightNew = widthNew - 1;
76475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropBottomNew = heightNew - 1;
77f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
78f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
79475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (static_cast<int32_t>(mColorFormat) == colorFormatNew &&
80475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mWidth == widthNew &&
81475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mHeight == heightNew &&
82475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropLeft == cropLeftNew &&
83475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropTop == cropTopNew &&
84475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropRight == cropRightNew &&
85475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropBottom == cropBottomNew) {
86475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        // Nothing changed, no need to reset renderer.
87475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        return;
88475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
89475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
90475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew);
91475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mWidth = widthNew;
92475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mHeight = heightNew;
93475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropLeft = cropLeftNew;
94475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropTop = cropTopNew;
95475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropRight = cropRightNew;
96475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropBottom = cropBottomNew;
97475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropWidth = mCropRight - mCropLeft + 1;
993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropHeight = mCropBottom - mCropTop + 1;
1003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
101448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // by default convert everything to RGB565
102448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    int halFormat = HAL_PIXEL_FORMAT_RGB_565;
103448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    size_t bufWidth = mCropWidth;
104448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    size_t bufHeight = mCropHeight;
105448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
106448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // hardware has YUV12 and RGBA8888 support, so convert known formats
107448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    if (!runningInEmulator()) {
108448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        switch (mColorFormat) {
109448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_FormatYUV420Planar:
1103f9b0cc8c71ce6064bf2ed5c3ab5b48e74937385Lajos Molnar            case OMX_COLOR_FormatYUV420SemiPlanar:
111448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
112448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
1139dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                halFormat = HAL_PIXEL_FORMAT_YV12;
1149dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufWidth = (mCropWidth + 1) & ~1;
1159dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufHeight = (mCropHeight + 1) & ~1;
1169dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                break;
1179dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            }
118448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_Format24bitRGB888:
119448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
120448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                halFormat = HAL_PIXEL_FORMAT_RGB_888;
121448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufWidth = (mCropWidth + 1) & ~1;
122448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufHeight = (mCropHeight + 1) & ~1;
123448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
124448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
125448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_Format32bitARGB8888:
12646b451fab7a26c501d4d6c87a354f70531c19d13David Smith            case OMX_COLOR_Format32BitRGBA8888:
127448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
128448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                halFormat = HAL_PIXEL_FORMAT_RGBA_8888;
129448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufWidth = (mCropWidth + 1) & ~1;
130448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufHeight = (mCropHeight + 1) & ~1;
131448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
132448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
133448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            default:
134448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
135448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
136448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
1375e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
138448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    }
1395e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
140448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    if (halFormat == HAL_PIXEL_FORMAT_RGB_565) {
141448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        mConverter = new ColorConverter(
142448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                mColorFormat, OMX_COLOR_Format16bitRGB565);
143448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        CHECK(mConverter->isValid());
14489e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
14589e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
1461173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK(mNativeWindow != NULL);
1473571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropWidth > 0);
1483571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropHeight > 0);
1495daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
1505daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
1531173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow.get(),
1545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
155103487c0cb5c06f47225484486a98bc84745a059Andreas Huber            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1579bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    CHECK_EQ(0,
1589bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(
1599bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            mNativeWindow.get(),
1609bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1619bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
1625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
163475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_dimensions(
1641173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
1655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
166475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                bufHeight));
167475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_format(
168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(),
1695daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
170ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
17125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    // NOTE: native window uses extended right-bottom coordinate
17225a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    android_native_rect_t crop;
17325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.left = mCropLeft;
17425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.top = mCropTop;
17525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.right = mCropRight + 1;
17625a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.bottom = mCropBottom + 1;
17725a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
17825a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);
17925a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
18025a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));
18125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
182475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t rotationDegrees;
183475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findInt32("rotation-degrees", &rotationDegrees)) {
184475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        rotationDegrees = 0;
185475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
186ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
187ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
188ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
189ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
190ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
191ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
192ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
193ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
194ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
195475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_transform(
196475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(), transform));
1975e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
1985e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
200760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        const void *data, size_t size, int64_t timestampNs,
201475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        void* /*platformPrivate*/, const sp<AMessage>& format) {
202475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    resetFormatIfChanged(format);
203475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
2048ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
2055de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
2061e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(),
2071e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            &buf)) != 0) {
2085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::dequeueBuffer returned error %d", err);
2095de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
2105de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2115de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
2125daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
2135daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
2143571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
2155daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
2165daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
2175daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
2185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
2195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
220448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // TODO move the other conversions also into ColorConverter, and
221448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth)
2225daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
2235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
224f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
225f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
2263571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
227f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
228f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
2293571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
2303571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
231760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 / 2 > size) {
232760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
233760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
2345e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
235448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_u =
236448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                (const uint8_t *)data + mWidth * mHeight;
2375e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
2385e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2395e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2405e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2415e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2425e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2435e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2445e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2455e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2463571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2473571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2485e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2495e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
2505e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
2515e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2525e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2533571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2543571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
2553571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
2565e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2575e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
2585e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
2595e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
2605e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
2615e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2629578a90c214e430334b8696999f921290c35d067Lajos Molnar    } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
2639578a90c214e430334b8696999f921290c35d067Lajos Molnar            || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
264760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 / 2 > size) {
265760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
266760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
267448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_y = (const uint8_t *)data;
268448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_uv = (const uint8_t *)data
269448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                + mWidth * (mHeight - mCropTop / 2);
2703571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2713571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2723571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2733571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2743571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2753571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2763571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2773571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2783571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2793571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2803571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2813571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2823571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2833571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2843571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2853571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2863571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2873571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
2883571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
2893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
2903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
2913571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
2923571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
2943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
2953571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
2963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
297448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else if (mColorFormat == OMX_COLOR_Format24bitRGB888) {
298760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 > size) {
299760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
300760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
301448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t* srcPtr = (uint8_t*)data;
302448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t* dstPtr = (uint8_t*)dst;
303448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
304448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
305448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            memcpy(dstPtr, srcPtr, mCropWidth * 3);
306448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            srcPtr += mWidth * 3;
307448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            dstPtr += buf->stride * 3;
308448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        }
309448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else if (mColorFormat == OMX_COLOR_Format32bitARGB8888) {
310760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 4 > size) {
311760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
312760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
313448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t *srcPtr, *dstPtr;
314448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
315448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
316448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            srcPtr = (uint8_t*)data + mWidth * 4 * y;
317448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            dstPtr = (uint8_t*)dst + buf->stride * 4 * y;
318448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            for (size_t x = 0; x < (size_t)mCropWidth; ++x) {
319448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                uint8_t a = *srcPtr++;
320448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                for (size_t i = 0; i < 3; ++i) {   // copy RGB
321448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                    *dstPtr++ = *srcPtr++;
322448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                }
323448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                *dstPtr++ = a;  // alpha last (ARGB to RGBA)
324448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
325448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        }
32646b451fab7a26c501d4d6c87a354f70531c19d13David Smith    } else if (mColorFormat == OMX_COLOR_Format32BitRGBA8888) {
327760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 4 > size) {
328760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
329760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
33046b451fab7a26c501d4d6c87a354f70531c19d13David Smith        uint8_t* srcPtr = (uint8_t*)data;
33146b451fab7a26c501d4d6c87a354f70531c19d13David Smith        uint8_t* dstPtr = (uint8_t*)dst;
33246b451fab7a26c501d4d6c87a354f70531c19d13David Smith
33346b451fab7a26c501d4d6c87a354f70531c19d13David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
33446b451fab7a26c501d4d6c87a354f70531c19d13David Smith            memcpy(dstPtr, srcPtr, mCropWidth * 4);
33546b451fab7a26c501d4d6c87a354f70531c19d13David Smith            srcPtr += mWidth * 4;
33646b451fab7a26c501d4d6c87a354f70531c19d13David Smith            dstPtr += buf->stride * 4;
33746b451fab7a26c501d4d6c87a354f70531c19d13David Smith        }
338448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else {
339448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        LOG_ALWAYS_FATAL("bad color format %#x", mColorFormat);
3405daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
3414265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
342760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jiaskip_copying:
3435daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
3444265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
345908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    if ((err = native_window_set_buffers_timestamp(mNativeWindow.get(),
346908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar            timestampNs)) != 0) {
347908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar        ALOGW("Surface::set_buffers_timestamp returned error %d", err);
348908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    }
349908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar
3501e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf,
3511e5b2b3361ddd07259bf4b29820ca4aa5f3a861bJamie Gennis            -1)) != 0) {
3525ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::queueBuffer returned error %d", err);
3535de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
3545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
3554265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
3564265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
358