1cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza/* 2cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * Copyright 2013 The Android Open Source Project 3cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * 4cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * Licensed under the Apache License, Version 2.0 (the "License"); 5cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * you may not use this file except in compliance with the License. 6cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * You may obtain a copy of the License at 7cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * 8cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * http://www.apache.org/licenses/LICENSE-2.0 9cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * 10cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * Unless required by applicable law or agreed to in writing, software 11cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * distributed under the License is distributed on an "AS IS" BASIS, 12cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * See the License for the specific language governing permissions and 14cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza * limitations under the License. 15cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza */ 16cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 17cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza#include "FillBuffer.h" 18cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 19cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza#include <ui/GraphicBuffer.h> 20cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 21cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza#include <gtest/gtest.h> 22cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 23cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stozanamespace android { 24cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 25cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stozavoid fillYV12Buffer(uint8_t* buf, int w, int h, int stride) { 26cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const int blockWidth = w > 16 ? w / 16 : 1; 27cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const int blockHeight = h > 16 ? h / 16 : 1; 28cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const int yuvTexOffsetY = 0; 29cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideY = stride; 30cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexOffsetV = yuvTexStrideY * h; 31cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 32cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 33cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideU = yuvTexStrideV; 34cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int x = 0; x < w; x++) { 35cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int y = 0; y < h; y++) { 36cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int parityX = (x / blockWidth) & 1; 37cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int parityY = (y / blockHeight) & 1; 38cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza unsigned char intensity = (parityX ^ parityY) ? 63 : 191; 39cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; 40cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza if (x < w / 2 && y < h / 2) { 41cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; 42cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza if (x * 2 < w / 2 && y * 2 < h / 2) { 43cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = 44cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = 45cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = 46cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = 47cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza intensity; 48cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 49cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 50cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 51cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 52cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza} 53cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 54cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stozavoid fillYV12BufferRect(uint8_t* buf, int w, int h, int stride, 55cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const android_native_rect_t& rect) { 56cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const int yuvTexOffsetY = 0; 57cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideY = stride; 58cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexOffsetV = yuvTexStrideY * h; 59cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 60cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 61cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int yuvTexStrideU = yuvTexStrideV; 62cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int x = 0; x < w; x++) { 63cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int y = 0; y < h; y++) { 64cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza bool inside = rect.left <= x && x < rect.right && 65cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza rect.top <= y && y < rect.bottom; 66cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64; 67cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza if (x < w / 2 && y < h / 2) { 68cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza bool inside = rect.left <= 2*x && 2*x < rect.right && 69cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza rect.top <= 2*y && 2*y < rect.bottom; 70cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16; 71cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = 72cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza inside ? 16 : 255; 73cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 74cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 75cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 76cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza} 77cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 78cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stozavoid fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) { 79cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza const size_t PIXEL_SIZE = 4; 80cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int x = 0; x < w; x++) { 81cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int y = 0; y < h; y++) { 82cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza off_t offset = (y * stride + x) * PIXEL_SIZE; 83cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza for (int c = 0; c < 4; c++) { 84cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int parityX = (x / (1 << (c+2))) & 1; 85cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza int parityY = (y / (1 << (c+2))) & 1; 86cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza buf[offset + c] = (parityX ^ parityY) ? 231 : 35; 87cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 88cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 89cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza } 90cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza} 91cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 92cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stozavoid produceOneRGBA8Frame(const sp<ANativeWindow>& anw) { 93cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza android_native_buffer_t* anb; 94cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza ASSERT_EQ(NO_ERROR, native_window_dequeue_buffer_and_wait(anw.get(), 95cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza &anb)); 96cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza ASSERT_TRUE(anb != NULL); 97cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 98cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 99cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza 100cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza uint8_t* img = NULL; 101cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza ASSERT_EQ(NO_ERROR, buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, 102cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza (void**)(&img))); 103cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza fillRGBA8Buffer(img, buf->getWidth(), buf->getHeight(), buf->getStride()); 104cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza ASSERT_EQ(NO_ERROR, buf->unlock()); 105cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf->getNativeBuffer(), 106cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza -1)); 107cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza} 108cb1fcdedaaf95acabeac6a2d5bff423d6ca62296Dan Stoza} // namespace android 109