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
41505aab41c0e8e79a49d4506344fcd9d220d5965bChong ZhangSoftwareRenderer::SoftwareRenderer(
42505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        const sp<ANativeWindow> &nativeWindow, int32_t rotation)
43475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    : mColorFormat(OMX_COLOR_FormatUnused),
44475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mConverter(NULL),
455daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
46475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mNativeWindow(nativeWindow),
47475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mWidth(0),
48475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mHeight(0),
49475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropLeft(0),
50475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropTop(0),
51475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropRight(0),
52475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropBottom(0),
53475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu      mCropWidth(0),
54505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mCropHeight(0),
55505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang      mRotationDegrees(rotation) {
56475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
57475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
58475da7ef08c05a482ced8d318832cf5aa1141affRonghua WuSoftwareRenderer::~SoftwareRenderer() {
59475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    delete mConverter;
60475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mConverter = NULL;
61475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu}
62475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
63475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wuvoid SoftwareRenderer::resetFormatIfChanged(const sp<AMessage> &format) {
64475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format != NULL);
65475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
66475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t colorFormatNew;
67475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK(format->findInt32("color-format", &colorFormatNew));
68475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
69475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t widthNew, heightNew;
70a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu    CHECK(format->findInt32("stride", &widthNew));
71a694dd0ce2caaf921f7bc894df87a5d52594b4ebRonghua Wu    CHECK(format->findInt32("slice-height", &heightNew));
72475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
73475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t cropLeftNew, cropTopNew, cropRightNew, cropBottomNew;
74475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findRect(
75475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu            "crop", &cropLeftNew, &cropTopNew, &cropRightNew, &cropBottomNew)) {
76475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropLeftNew = cropTopNew = 0;
77475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropRightNew = widthNew - 1;
78475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        cropBottomNew = heightNew - 1;
79f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
80f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
81475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (static_cast<int32_t>(mColorFormat) == colorFormatNew &&
82475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mWidth == widthNew &&
83475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mHeight == heightNew &&
84475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropLeft == cropLeftNew &&
85475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropTop == cropTopNew &&
86475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropRight == cropRightNew &&
87475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        mCropBottom == cropBottomNew) {
88475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        // Nothing changed, no need to reset renderer.
89475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        return;
90475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
91475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
92475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mColorFormat = static_cast<OMX_COLOR_FORMATTYPE>(colorFormatNew);
93475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mWidth = widthNew;
94475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mHeight = heightNew;
95475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropLeft = cropLeftNew;
96475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropTop = cropTopNew;
97475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropRight = cropRightNew;
98475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    mCropBottom = cropBottomNew;
99475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
1003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropWidth = mCropRight - mCropLeft + 1;
1013571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    mCropHeight = mCropBottom - mCropTop + 1;
1023571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
103448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // by default convert everything to RGB565
104448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    int halFormat = HAL_PIXEL_FORMAT_RGB_565;
105448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    size_t bufWidth = mCropWidth;
106448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    size_t bufHeight = mCropHeight;
107448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
108448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // hardware has YUV12 and RGBA8888 support, so convert known formats
109448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    if (!runningInEmulator()) {
110448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        switch (mColorFormat) {
111448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_FormatYUV420Planar:
1123f9b0cc8c71ce6064bf2ed5c3ab5b48e74937385Lajos Molnar            case OMX_COLOR_FormatYUV420SemiPlanar:
113448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar:
114448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
1159dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                halFormat = HAL_PIXEL_FORMAT_YV12;
1169dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufWidth = (mCropWidth + 1) & ~1;
1179dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                bufHeight = (mCropHeight + 1) & ~1;
1189dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber                break;
1199dc4c66f36ca0158b470c78b0929cd9dd929a375Andreas Huber            }
120448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_Format24bitRGB888:
121448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
122448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                halFormat = HAL_PIXEL_FORMAT_RGB_888;
123448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufWidth = (mCropWidth + 1) & ~1;
124448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufHeight = (mCropHeight + 1) & ~1;
125448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
126448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
127448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            case OMX_COLOR_Format32bitARGB8888:
12846b451fab7a26c501d4d6c87a354f70531c19d13David Smith            case OMX_COLOR_Format32BitRGBA8888:
129448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
130448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                halFormat = HAL_PIXEL_FORMAT_RGBA_8888;
131448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufWidth = (mCropWidth + 1) & ~1;
132448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                bufHeight = (mCropHeight + 1) & ~1;
133448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
134448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
135448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            default:
136448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            {
137448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                break;
138448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
1395e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
140448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    }
1415e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
142448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    if (halFormat == HAL_PIXEL_FORMAT_RGB_565) {
143448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        mConverter = new ColorConverter(
144448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                mColorFormat, OMX_COLOR_Format16bitRGB565);
145448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        CHECK(mConverter->isValid());
14689e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
14789e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
1481173118eace0e9e347cb007f0da817cee87579edGlenn Kasten    CHECK(mNativeWindow != NULL);
1493571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropWidth > 0);
1503571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    CHECK(mCropHeight > 0);
1515daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
1525daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1535daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
1545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
1551173118eace0e9e347cb007f0da817cee87579edGlenn Kasten            mNativeWindow.get(),
1565daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
157103487c0cb5c06f47225484486a98bc84745a059Andreas Huber            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1599bc7af17974f448291a44912566ec7472a0d798bMathias Agopian    CHECK_EQ(0,
1609bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(
1619bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            mNativeWindow.get(),
1629bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
1639bc7af17974f448291a44912566ec7472a0d798bMathias Agopian
1645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
165475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_dimensions(
1661173118eace0e9e347cb007f0da817cee87579edGlenn Kasten                mNativeWindow.get(),
1675e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber                bufWidth,
168475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                bufHeight));
169475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_format(
170475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(),
1715daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
172ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
17325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    // NOTE: native window uses extended right-bottom coordinate
17425a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    android_native_rect_t crop;
17525a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.left = mCropLeft;
17625a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.top = mCropTop;
17725a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.right = mCropRight + 1;
17825a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    crop.bottom = mCropBottom + 1;
17925a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    ALOGV("setting crop: [%d, %d, %d, %d] for size [%zu, %zu]",
18025a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar          crop.left, crop.top, crop.right, crop.bottom, bufWidth, bufHeight);
18125a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
18225a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar    CHECK_EQ(0, native_window_set_crop(mNativeWindow.get(), &crop));
18325a147aaad0ce30da8db763054d963ceaedb4065Lajos Molnar
184475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    int32_t rotationDegrees;
185475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    if (!format->findInt32("rotation-degrees", &rotationDegrees)) {
186505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang        rotationDegrees = mRotationDegrees;
187475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    }
188ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
189ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
190ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
191ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
192ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
193ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
194ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
195ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
196ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
197475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    CHECK_EQ(0, native_window_set_buffers_transform(
198475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu                mNativeWindow.get(), transform));
1995e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber}
2005e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
20190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarvoid SoftwareRenderer::clearTracker() {
20290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    mRenderTracker.clear(-1 /* lastRenderTimeNs */);
20390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar}
20490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
20590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnarstd::list<FrameRenderTracker::Info> SoftwareRenderer::render(
20690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        const void *data, size_t size, int64_t mediaTimeUs, nsecs_t renderTimeNs,
207475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu        void* /*platformPrivate*/, const sp<AMessage>& format) {
208475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu    resetFormatIfChanged(format);
20990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    FrameRenderTracker::Info *info = NULL;
210475da7ef08c05a482ced8d318832cf5aa1141affRonghua Wu
2118ce2364512f7c32c824f5ec5719688830ba72427Iliyan Malchev    ANativeWindowBuffer *buf;
21290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    int fenceFd = -1;
21390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf, &fenceFd);
21490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (err == 0 && fenceFd >= 0) {
21590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        info = mRenderTracker.updateInfoForDequeuedBuffer(buf, fenceFd, 0);
21690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        sp<Fence> fence = new Fence(fenceFd);
21790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        err = fence->waitForever("SoftwareRenderer::render");
21890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
21990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (err != 0) {
2205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::dequeueBuffer returned error %d", err);
22190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // complete (drop) dequeued frame if fence wait failed; otherwise,
22290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        // this returns an empty list as no frames should have rendered and not yet returned.
22390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        return mRenderTracker.checkFencesAndGetRenderedFrames(info, false /* dropIncomplete */);
2245de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
2255de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
2265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
2275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
2283571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    Rect bounds(mCropWidth, mCropHeight);
2295daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
2305daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
2315daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
2325daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
2335daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
234448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // TODO move the other conversions also into ColorConverter, and
235448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    // fix cropping issues (when mCropLeft/Top != 0 or mWidth != mCropWidth)
2365daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
2375daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
238f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
239f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
2403571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
241f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
242f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
2433571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                0, 0, mCropWidth - 1, mCropHeight - 1);
2443571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber    } else if (mColorFormat == OMX_COLOR_FormatYUV420Planar) {
245760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 / 2 > size) {
246760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
247760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
2485e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_y = (const uint8_t *)data;
249448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_u =
250448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                (const uint8_t *)data + mWidth * mHeight;
2515e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        const uint8_t *src_v = src_u + (mWidth / 2 * mHeight / 2);
2525e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2535e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2545e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2555e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2565e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2575e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2585e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2595e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2603571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2613571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2625e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2635e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_y += mWidth;
2645e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_y += buf->stride;
2655e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2665e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2673571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
2683571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_u, src_u, (mCropWidth + 1) / 2);
2693571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_v, src_v, (mCropWidth + 1) / 2);
2705e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber
2715e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_u += mWidth / 2;
2725e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            src_v += mWidth / 2;
2735e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_u += dst_c_stride;
2745e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber            dst_v += dst_c_stride;
2755e97c8861ef81d07cf1e304c1c1bed09b84513d4Andreas Huber        }
2769578a90c214e430334b8696999f921290c35d067Lajos Molnar    } else if (mColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
2779578a90c214e430334b8696999f921290c35d067Lajos Molnar            || mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
278760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 / 2 > size) {
279760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
280760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
281448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_y = (const uint8_t *)data;
282448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        const uint8_t *src_uv = (const uint8_t *)data
283448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                + mWidth * (mHeight - mCropTop / 2);
2843571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2853571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_y = (uint8_t *)dst;
2863571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2873571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_y_size = buf->stride * buf->height;
2883571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_stride = ALIGN(buf->stride / 2, 16);
2893571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        size_t dst_c_size = dst_c_stride * buf->height / 2;
2903571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_v = dst_y + dst_y_size;
2913571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        uint8_t *dst_u = dst_v + dst_c_size;
2923571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2933571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < mCropHeight; ++y) {
2943571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            memcpy(dst_y, src_y, mCropWidth);
2953571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
2963571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_y += mWidth;
2973571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_y += buf->stride;
2983571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
2993571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
3003571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        for (int y = 0; y < (mCropHeight + 1) / 2; ++y) {
3013571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            size_t tmp = (mCropWidth + 1) / 2;
3023571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            for (size_t x = 0; x < tmp; ++x) {
3033571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_u[x] = src_uv[2 * x];
3043571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber                dst_v[x] = src_uv[2 * x + 1];
3053571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            }
3063571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber
3073571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            src_uv += mWidth;
3083571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_u += dst_c_stride;
3093571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber            dst_v += dst_c_stride;
3103571d50a2582bc9c63f09cd81b4f490ea3522bd9Andreas Huber        }
311448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else if (mColorFormat == OMX_COLOR_Format24bitRGB888) {
312760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 3 > size) {
313760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
314760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
315448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t* srcPtr = (uint8_t*)data;
316448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t* dstPtr = (uint8_t*)dst;
317448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
318448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
319448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            memcpy(dstPtr, srcPtr, mCropWidth * 3);
320448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            srcPtr += mWidth * 3;
321448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            dstPtr += buf->stride * 3;
322448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        }
323448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else if (mColorFormat == OMX_COLOR_Format32bitARGB8888) {
324760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 4 > size) {
325760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
326760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
327448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        uint8_t *srcPtr, *dstPtr;
328448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith
329448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
330448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            srcPtr = (uint8_t*)data + mWidth * 4 * y;
331448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            dstPtr = (uint8_t*)dst + buf->stride * 4 * y;
332448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            for (size_t x = 0; x < (size_t)mCropWidth; ++x) {
333448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                uint8_t a = *srcPtr++;
334448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                for (size_t i = 0; i < 3; ++i) {   // copy RGB
335448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                    *dstPtr++ = *srcPtr++;
336448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                }
337448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith                *dstPtr++ = a;  // alpha last (ARGB to RGBA)
338448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith            }
339448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        }
34046b451fab7a26c501d4d6c87a354f70531c19d13David Smith    } else if (mColorFormat == OMX_COLOR_Format32BitRGBA8888) {
341760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        if ((size_t)mWidth * mHeight * 4 > size) {
342760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia            goto skip_copying;
343760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jia        }
34446b451fab7a26c501d4d6c87a354f70531c19d13David Smith        uint8_t* srcPtr = (uint8_t*)data;
34546b451fab7a26c501d4d6c87a354f70531c19d13David Smith        uint8_t* dstPtr = (uint8_t*)dst;
34646b451fab7a26c501d4d6c87a354f70531c19d13David Smith
34746b451fab7a26c501d4d6c87a354f70531c19d13David Smith        for (size_t y = 0; y < (size_t)mCropHeight; ++y) {
34846b451fab7a26c501d4d6c87a354f70531c19d13David Smith            memcpy(dstPtr, srcPtr, mCropWidth * 4);
34946b451fab7a26c501d4d6c87a354f70531c19d13David Smith            srcPtr += mWidth * 4;
35046b451fab7a26c501d4d6c87a354f70531c19d13David Smith            dstPtr += buf->stride * 4;
35146b451fab7a26c501d4d6c87a354f70531c19d13David Smith        }
352448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith    } else {
353448517af18bd2f91c2194c2f24b22561de3ea2e4David Smith        LOG_ALWAYS_FATAL("bad color format %#x", mColorFormat);
3545daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
3554265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
356760f92f8b6da9c9cf128cb18fe3c09402fdde6cdWei Jiaskip_copying:
3575daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
3584265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
35990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if (renderTimeNs >= 0) {
36090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        if ((err = native_window_set_buffers_timestamp(mNativeWindow.get(),
36190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                renderTimeNs)) != 0) {
36290fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar            ALOGW("Surface::set_buffers_timestamp returned error %d", err);
36390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        }
364908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar    }
365908ea6603c64e29e40277a74c9fb0e776c097830Lajos Molnar
366b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // TODO: propagate color aspects to software renderer to allow better
367b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    // color conversion to RGB. For now, just mark dataspace for YUV rendering.
368b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    android_dataspace dataSpace;
369b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    if (format->findInt32("android._dataspace", (int32_t *)&dataSpace) && dataSpace != mDataSpace) {
370b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        ALOGD("setting dataspace on output surface to #%x", dataSpace);
371b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        if ((err = native_window_set_buffers_data_space(mNativeWindow.get(), dataSpace))) {
372b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar            ALOGW("failed to set dataspace on surface (%d)", err);
373b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        }
374b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar        mDataSpace = dataSpace;
375b77d03b62cb743d0faf74b54aa466b4d220b5e61Lajos Molnar    }
37690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf, -1)) != 0) {
3775ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Surface::queueBuffer returned error %d", err);
37890fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    } else {
37990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        mRenderTracker.onFrameQueued(mediaTimeUs, (GraphicBuffer *)buf, Fence::NO_FENCE);
3805de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
38190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
3825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
38390fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    return mRenderTracker.checkFencesAndGetRenderedFrames(info, info != NULL /* dropIncomplete */);
3844265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
3854265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
38620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
387