Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2009 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #define LOG_TAG "SoftwareRenderer" |
| 18 | #include <utils/Log.h> |
| 19 | |
Andreas Huber | bd7b43b | 2009-10-13 10:22:55 -0700 | [diff] [blame] | 20 | #include "../include/SoftwareRenderer.h" |
| 21 | |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 22 | #include <binder/MemoryHeapBase.h> |
Andreas Huber | cfde87b | 2010-01-29 14:56:33 -0800 | [diff] [blame] | 23 | #include <binder/MemoryHeapPmem.h> |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 24 | #include <media/stagefright/foundation/ADebug.h> |
| 25 | #include <media/stagefright/MetaData.h> |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 26 | #include <surfaceflinger/Surface.h> |
| 27 | #include <ui/android_native_buffer.h> |
| 28 | #include <ui/GraphicBufferMapper.h> |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 29 | #include <gui/ISurfaceTexture.h> |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 30 | |
| 31 | namespace android { |
| 32 | |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 33 | SoftwareRenderer::SoftwareRenderer( |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 34 | const sp<ANativeWindow> &nativeWindow, const sp<MetaData> &meta) |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 35 | : mConverter(NULL), |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 36 | mYUVMode(None), |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 37 | mNativeWindow(nativeWindow) { |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 38 | int32_t tmp; |
| 39 | CHECK(meta->findInt32(kKeyColorFormat, &tmp)); |
| 40 | mColorFormat = (OMX_COLOR_FORMATTYPE)tmp; |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 41 | |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 42 | CHECK(meta->findInt32(kKeyWidth, &mWidth)); |
| 43 | CHECK(meta->findInt32(kKeyHeight, &mHeight)); |
| 44 | |
| 45 | if (!meta->findRect( |
| 46 | kKeyCropRect, |
| 47 | &mCropLeft, &mCropTop, &mCropRight, &mCropBottom)) { |
| 48 | mCropLeft = mCropTop = 0; |
| 49 | mCropRight = mWidth - 1; |
| 50 | mCropBottom = mHeight - 1; |
| 51 | } |
| 52 | |
| 53 | int32_t rotationDegrees; |
| 54 | if (!meta->findInt32(kKeyRotation, &rotationDegrees)) { |
| 55 | rotationDegrees = 0; |
| 56 | } |
Andreas Huber | 08478d1 | 2010-10-07 13:48:34 -0700 | [diff] [blame] | 57 | |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 58 | int halFormat; |
| 59 | switch (mColorFormat) { |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 60 | default: |
| 61 | halFormat = HAL_PIXEL_FORMAT_RGB_565; |
| 62 | |
| 63 | mConverter = new ColorConverter( |
| 64 | mColorFormat, OMX_COLOR_Format16bitRGB565); |
| 65 | CHECK(mConverter->isValid()); |
| 66 | break; |
Andreas Huber | cfde87b | 2010-01-29 14:56:33 -0800 | [diff] [blame] | 67 | } |
| 68 | |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 69 | CHECK(mNativeWindow != NULL); |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 70 | CHECK(mWidth > 0); |
| 71 | CHECK(mHeight > 0); |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 72 | CHECK(mConverter == NULL || mConverter->isValid()); |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 73 | |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 74 | CHECK_EQ(0, |
| 75 | native_window_set_usage( |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 76 | mNativeWindow.get(), |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 77 | GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN |
Jamie Gennis | b04c1503 | 2010-11-17 18:57:13 -0800 | [diff] [blame] | 78 | | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP)); |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 79 | |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 80 | // Width must be multiple of 32??? |
| 81 | CHECK_EQ(0, native_window_set_buffers_geometry( |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 82 | mNativeWindow.get(), |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 83 | mCropRight - mCropLeft + 1, |
| 84 | mCropBottom - mCropTop + 1, |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 85 | halFormat)); |
Andreas Huber | 940c866 | 2010-11-16 15:26:30 -0800 | [diff] [blame] | 86 | |
| 87 | uint32_t transform; |
| 88 | switch (rotationDegrees) { |
| 89 | case 0: transform = 0; break; |
| 90 | case 90: transform = HAL_TRANSFORM_ROT_90; break; |
| 91 | case 180: transform = HAL_TRANSFORM_ROT_180; break; |
| 92 | case 270: transform = HAL_TRANSFORM_ROT_270; break; |
| 93 | default: transform = 0; break; |
| 94 | } |
| 95 | |
| 96 | if (transform) { |
| 97 | CHECK_EQ(0, native_window_set_buffers_transform( |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 98 | mNativeWindow.get(), transform)); |
Andreas Huber | 940c866 | 2010-11-16 15:26:30 -0800 | [diff] [blame] | 99 | } |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | SoftwareRenderer::~SoftwareRenderer() { |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 103 | delete mConverter; |
| 104 | mConverter = NULL; |
| 105 | } |
| 106 | |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 107 | void SoftwareRenderer::render( |
| 108 | const void *data, size_t size, void *platformPrivate) { |
Iliyan Malchev | b2a153a | 2011-05-01 11:33:26 -0700 | [diff] [blame] | 109 | ANativeWindowBuffer *buf; |
Andreas Huber | 94e6b66 | 2010-09-07 14:11:47 -0700 | [diff] [blame] | 110 | int err; |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 111 | if ((err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf)) != 0) { |
Andreas Huber | 94e6b66 | 2010-09-07 14:11:47 -0700 | [diff] [blame] | 112 | LOGW("Surface::dequeueBuffer returned error %d", err); |
| 113 | return; |
| 114 | } |
| 115 | |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 116 | CHECK_EQ(0, mNativeWindow->lockBuffer(mNativeWindow.get(), buf)); |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 117 | |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 118 | GraphicBufferMapper &mapper = GraphicBufferMapper::get(); |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 119 | |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 120 | Rect bounds(mWidth, mHeight); |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 121 | |
| 122 | void *dst; |
| 123 | CHECK_EQ(0, mapper.lock( |
| 124 | buf->handle, GRALLOC_USAGE_SW_WRITE_OFTEN, bounds, &dst)); |
| 125 | |
| 126 | if (mConverter) { |
| 127 | mConverter->convert( |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 128 | data, |
| 129 | mWidth, mHeight, |
| 130 | mCropLeft, mCropTop, mCropRight, mCropBottom, |
| 131 | dst, |
| 132 | buf->stride, buf->height, |
| 133 | 0, 0, |
| 134 | mCropRight - mCropLeft, |
| 135 | mCropBottom - mCropTop); |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 136 | } else { |
Andreas Huber | 1bb0ffd | 2010-11-22 13:06:35 -0800 | [diff] [blame] | 137 | TRESPASS(); |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 138 | } |
| 139 | |
| 140 | CHECK_EQ(0, mapper.unlock(buf->handle)); |
| 141 | |
Glenn Kasten | cc562a3 | 2011-02-08 17:26:17 -0800 | [diff] [blame] | 142 | if ((err = mNativeWindow->queueBuffer(mNativeWindow.get(), buf)) != 0) { |
Andreas Huber | 94e6b66 | 2010-09-07 14:11:47 -0700 | [diff] [blame] | 143 | LOGW("Surface::queueBuffer returned error %d", err); |
| 144 | } |
Andreas Huber | e3c0183 | 2010-08-16 08:49:37 -0700 | [diff] [blame] | 145 | buf = NULL; |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 146 | } |
| 147 | |
Andreas Huber | e46b7be | 2009-07-14 16:56:47 -0700 | [diff] [blame] | 148 | } // namespace android |