SoftwareRenderer.cpp revision f5ab57c2d5e02af7483c94eddb177e4f5c9e9892
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>
24f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/foundation/ADebug.h>
25f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber#include <media/stagefright/MetaData.h>
265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <surfaceflinger/Surface.h>
275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/android_native_buffer.h>
285daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber#include <ui/GraphicBufferMapper.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::SoftwareRenderer(
33f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        const sp<Surface> &surface, const sp<MetaData> &meta)
34f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    : mConverter(NULL),
355daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber      mYUVMode(None),
36f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber      mSurface(surface) {
37f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t tmp;
38f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyColorFormat, &tmp));
39f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    mColorFormat = (OMX_COLOR_FORMATTYPE)tmp;
40f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
41f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyWidth, &mWidth));
42f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(meta->findInt32(kKeyHeight, &mHeight));
43f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
44f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findRect(
45f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                kKeyCropRect,
46f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) {
47f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropLeft = mCropTop = 0;
48f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropRight = mWidth - 1;
49f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        mCropBottom = mHeight - 1;
50f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
51f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber
52f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    int32_t rotationDegrees;
53f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    if (!meta->findInt32(kKeyRotation, &rotationDegrees)) {
54f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        rotationDegrees = 0;
55f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    }
56a240812f10335fe4c8677da824293b7e04aad7e9Andreas Huber
575daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    int halFormat;
585daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    switch (mColorFormat) {
595daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        default:
605daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            halFormat = HAL_PIXEL_FORMAT_RGB_565;
615daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
625daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mConverter = new ColorConverter(
635daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                    mColorFormat, OMX_COLOR_Format16bitRGB565);
645daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            CHECK(mConverter->isValid());
655daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            break;
6689e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber    }
6789e7fff6a5d7410815f42b4a55958a59d4463180Andreas Huber
685daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mSurface.get() != NULL);
69f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(mWidth > 0);
70f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    CHECK(mHeight > 0);
715daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK(mConverter == NULL || mConverter->isValid());
725daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
735daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0,
745daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            native_window_set_usage(
755daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            mSurface.get(),
765daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN
77c726bd8b7b9929fd917b01e5551a66ad5fe2c04eJamie Gennis            | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP));
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
795daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffer_count(mSurface.get(), 2));
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
815daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    // Width must be multiple of 32???
825daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, native_window_set_buffers_geometry(
83f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mSurface.get(),
84f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mCropRight - mCropLeft + 1,
85f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mCropBottom - mCropTop + 1,
865daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                halFormat));
87ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
88ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    uint32_t transform;
89ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    switch (rotationDegrees) {
90ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 0: transform = 0; break;
91ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 90: transform = HAL_TRANSFORM_ROT_90; break;
92ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 180: transform = HAL_TRANSFORM_ROT_180; break;
93ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        case 270: transform = HAL_TRANSFORM_ROT_270; break;
94ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        default: transform = 0; break;
95ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
96ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber
97ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    if (transform) {
98ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber        CHECK_EQ(0, native_window_set_buffers_transform(
99ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber                    mSurface.get(), transform));
100ba529e486dde15fe75ea1b48570f9d60a4cf3c48Andreas Huber    }
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSoftwareRenderer::~SoftwareRenderer() {
1045daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    delete mConverter;
1055daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    mConverter = NULL;
1065daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber}
1075daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid SoftwareRenderer::render(
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        const void *data, size_t size, void *platformPrivate) {
1105daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    android_native_buffer_t *buf;
1115de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    int err;
1125de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    if ((err = mSurface->dequeueBuffer(mSurface.get(), &buf)) != 0) {
1135de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::dequeueBuffer returned error %d", err);
1145de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        return;
1155de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1165de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber
1175daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mSurface->lockBuffer(mSurface.get(), buf));
1185daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1195daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
1205daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
121f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber    Rect bounds(mWidth, mHeight);
1225daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1235daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    void *dst;
1245daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.lock(
1255daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber                buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst));
1265daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber
1275daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    if (mConverter) {
1285daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber        mConverter->convert(
129f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                data,
130f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mWidth, mHeight,
131f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mCropLeft, mCropTop, mCropRight, mCropBottom,
132f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                dst,
133f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                buf->stride, buf->height,
134f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                0, 0,
135f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mCropRight - mCropLeft,
136f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber                mCropBottom - mCropTop);
1375daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    } else {
138f5ab57c2d5e02af7483c94eddb177e4f5c9e9892Andreas Huber        TRESPASS();
1395daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    }
1404265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
1415daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    CHECK_EQ(0, mapper.unlock(buf->handle));
1424265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
1435de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    if ((err = mSurface->queueBuffer(mSurface.get(), buf)) != 0) {
1445de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber        LOGW("Surface::queueBuffer returned error %d", err);
1455de4999e6dd8a3f2740d20e30e8a3fccdcb76362Andreas Huber    }
1465daeb129a2c2ba3d14ccd94af283b5f561c783eaAndreas Huber    buf = NULL;
1474265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber}
1484265a834394bfe14a008a2ac58fbbe388566ad07Andreas Huber
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
150