diff options
Diffstat (limited to 'libs/ui')
-rw-r--r-- | libs/ui/Fence.cpp | 40 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 37 | ||||
-rw-r--r-- | libs/ui/PixelFormat.cpp | 137 | ||||
-rw-r--r-- | libs/ui/Rect.cpp | 85 | ||||
-rw-r--r-- | libs/ui/Region.cpp | 9 | ||||
-rw-r--r-- | libs/ui/tests/Android.mk | 5 | ||||
-rw-r--r-- | libs/ui/tests/mat_test.cpp | 139 | ||||
-rw-r--r-- | libs/ui/tests/vec_test.cpp | 256 |
8 files changed, 528 insertions, 180 deletions
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp index 464ee86..93ec0ce 100644 --- a/libs/ui/Fence.cpp +++ b/libs/ui/Fence.cpp @@ -127,37 +127,49 @@ nsecs_t Fence::getSignalTime() const { } size_t Fence::getFlattenedSize() const { - return 0; + return 1; } size_t Fence::getFdCount() const { return isValid() ? 1 : 0; } -status_t Fence::flatten(void* buffer, size_t size, int fds[], - size_t count) const { - if (size != getFlattenedSize() || count != getFdCount()) { - return BAD_VALUE; +status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { + if (size < getFlattenedSize() || count < getFdCount()) { + return NO_MEMORY; } - + FlattenableUtils::write(buffer, size, getFdCount()); if (isValid()) { - fds[0] = mFenceFd; + *fds++ = mFenceFd; + count--; } return NO_ERROR; } -status_t Fence::unflatten(void const* buffer, size_t size, int fds[], - size_t count) { - if (size != 0 || (count != 0 && count != 1)) { - return BAD_VALUE; - } +status_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) { if (mFenceFd != -1) { // Don't unflatten if we already have a valid fd. return INVALID_OPERATION; } - if (count == 1) { - mFenceFd = fds[0]; + if (size < 1) { + return NO_MEMORY; + } + + size_t numFds; + FlattenableUtils::read(buffer, size, numFds); + + if (numFds > 1) { + return BAD_VALUE; + } + + if (count < numFds) { + return NO_MEMORY; + } + + if (numFds) { + mFenceFd = *fds++; + count--; } return NO_ERROR; diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 46a5a1d..8c325fd 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -36,8 +36,7 @@ namespace android { GraphicBuffer::GraphicBuffer() : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mIndex(-1) -{ + mInitCheck(NO_ERROR) { width = height = stride = @@ -49,7 +48,7 @@ GraphicBuffer::GraphicBuffer() GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat reqFormat, uint32_t reqUsage) : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mIndex(-1) + mInitCheck(NO_ERROR) { width = height = @@ -65,7 +64,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mIndex(-1) + mInitCheck(NO_ERROR) { width = w; height = h; @@ -78,7 +77,7 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership) : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), mBufferMapper(GraphicBufferMapper::get()), - mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer) + mInitCheck(NO_ERROR), mWrappedBuffer(buffer) { width = buffer->width; height = buffer->height; @@ -209,9 +208,7 @@ size_t GraphicBuffer::getFdCount() const { return handle ? handle->numFds : 0; } -status_t GraphicBuffer::flatten(void* buffer, size_t size, - int fds[], size_t count) const -{ +status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { size_t sizeNeeded = GraphicBuffer::getFlattenedSize(); if (size < sizeNeeded) return NO_MEMORY; @@ -236,12 +233,16 @@ status_t GraphicBuffer::flatten(void* buffer, size_t size, memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int)); } + buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded); + size -= sizeNeeded; + fds += handle->numFds; + count -= handle->numFds; + return NO_ERROR; } -status_t GraphicBuffer::unflatten(void const* buffer, size_t size, - int fds[], size_t count) -{ +status_t GraphicBuffer::unflatten( + void const*& buffer, size_t& size, int const*& fds, size_t& count) { if (size < 8*sizeof(int)) return NO_MEMORY; int const* buf = static_cast<int const*>(buffer); @@ -306,16 +307,12 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size, } } - return NO_ERROR; -} - + buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded); + size -= sizeNeeded; + fds += numFds; + count -= numFds; -void GraphicBuffer::setIndex(int index) { - mIndex = index; -} - -int GraphicBuffer::getIndex() const { - return mIndex; + return NO_ERROR; } // --------------------------------------------------------------------------- diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp index 3ced41d..d2d103a 100644 --- a/libs/ui/PixelFormat.cpp +++ b/libs/ui/PixelFormat.cpp @@ -21,123 +21,36 @@ namespace android { // ---------------------------------------------------------------------------- -static const int COMPONENT_YUV = 0xFF; - -struct Info { - size_t size; - size_t bitsPerPixel; - struct { - uint8_t ah; - uint8_t al; - uint8_t rh; - uint8_t rl; - uint8_t gh; - uint8_t gl; - uint8_t bh; - uint8_t bl; - }; - uint8_t components; -}; - -static Info const sPixelFormatInfos[] = { - { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, - { 4, 32, {32,24, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGBA }, - { 4, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB }, - { 3, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB }, - { 2, 16, { 0, 0, 16,11, 11, 5, 5, 0 }, PixelFormatInfo::RGB }, - { 4, 32, {32,24, 24,16, 16, 8, 8, 0 }, PixelFormatInfo::RGBA }, - { 2, 16, { 1, 0, 16,11, 11, 6, 6, 1 }, PixelFormatInfo::RGBA }, - { 2, 16, { 4, 0, 16,12, 12, 8, 8, 4 }, PixelFormatInfo::RGBA }, - { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA}, - { 1, 8, { 0, 0, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::L }, - { 2, 16, {16, 8, 8, 0, 8, 0, 8, 0 }, PixelFormatInfo::LA }, - { 1, 8, { 0, 0, 8, 5, 5, 2, 2, 0 }, PixelFormatInfo::RGB }, -}; - -static const Info* gGetPixelFormatTable(size_t* numEntries) { - if (numEntries) { - *numEntries = sizeof(sPixelFormatInfos)/sizeof(Info); - } - return sPixelFormatInfos; -} - -// ---------------------------------------------------------------------------- - -size_t PixelFormatInfo::getScanlineSize(unsigned int width) const -{ - size_t size; - if (components == COMPONENT_YUV) { - // YCbCr formats are different. - size = (width * bitsPerPixel)>>3; - } else { - size = width * bytesPerPixel; +ssize_t bytesPerPixel(PixelFormat format) { + switch (format) { + case PIXEL_FORMAT_RGBA_8888: + case PIXEL_FORMAT_RGBX_8888: + case PIXEL_FORMAT_BGRA_8888: + return 4; + case PIXEL_FORMAT_RGB_888: + return 3; + case PIXEL_FORMAT_RGB_565: + case PIXEL_FORMAT_RGBA_5551: + case PIXEL_FORMAT_RGBA_4444: + return 2; } - return size; + return BAD_VALUE; } -ssize_t bytesPerPixel(PixelFormat format) -{ - PixelFormatInfo info; - status_t err = getPixelFormatInfo(format, &info); - return (err < 0) ? err : info.bytesPerPixel; -} - -ssize_t bitsPerPixel(PixelFormat format) -{ - PixelFormatInfo info; - status_t err = getPixelFormatInfo(format, &info); - return (err < 0) ? err : info.bitsPerPixel; -} - -status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info) -{ - if (format <= 0) - return BAD_VALUE; - - if (info->version != sizeof(PixelFormatInfo)) - return INVALID_OPERATION; - - // YUV format from the HAL are handled here +ssize_t bitsPerPixel(PixelFormat format) { switch (format) { - case HAL_PIXEL_FORMAT_YCbCr_422_SP: - case HAL_PIXEL_FORMAT_YCbCr_422_I: - info->bitsPerPixel = 16; - goto done; - case HAL_PIXEL_FORMAT_YCrCb_420_SP: - case HAL_PIXEL_FORMAT_YV12: - info->bitsPerPixel = 12; - done: - info->format = format; - info->components = COMPONENT_YUV; - info->bytesPerPixel = 1; - info->h_alpha = 0; - info->l_alpha = 0; - info->h_red = info->h_green = info->h_blue = 8; - info->l_red = info->l_green = info->l_blue = 0; - return NO_ERROR; + case PIXEL_FORMAT_RGBA_8888: + case PIXEL_FORMAT_RGBX_8888: + case PIXEL_FORMAT_BGRA_8888: + return 32; + case PIXEL_FORMAT_RGB_888: + return 24; + case PIXEL_FORMAT_RGB_565: + case PIXEL_FORMAT_RGBA_5551: + case PIXEL_FORMAT_RGBA_4444: + return 16; } - - size_t numEntries; - const Info *i = gGetPixelFormatTable(&numEntries) + format; - bool valid = uint32_t(format) < numEntries; - if (!valid) { - return BAD_INDEX; - } - - info->format = format; - info->bytesPerPixel = i->size; - info->bitsPerPixel = i->bitsPerPixel; - info->h_alpha = i->ah; - info->l_alpha = i->al; - info->h_red = i->rh; - info->l_red = i->rl; - info->h_green = i->gh; - info->l_green = i->gl; - info->h_blue = i->bh; - info->l_blue = i->bl; - info->components = i->components; - - return NO_ERROR; + return BAD_VALUE; } // ---------------------------------------------------------------------------- diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp index c4dd55b..b480f3a 100644 --- a/libs/ui/Rect.cpp +++ b/libs/ui/Rect.cpp @@ -20,11 +20,11 @@ namespace android { static inline int32_t min(int32_t a, int32_t b) { - return (a<b) ? a : b; + return (a < b) ? a : b; } static inline int32_t max(int32_t a, int32_t b) { - return (a>b) ? a : b; + return (a > b) ? a : b; } void Rect::makeInvalid() { @@ -34,18 +34,17 @@ void Rect::makeInvalid() { bottom = -1; } -bool Rect::operator < (const Rect& rhs) const -{ - if (top<rhs.top) { +bool Rect::operator <(const Rect& rhs) const { + if (top < rhs.top) { return true; } else if (top == rhs.top) { if (left < rhs.left) { return true; } else if (left == rhs.left) { - if (bottom<rhs.bottom) { + if (bottom < rhs.bottom) { return true; } else if (bottom == rhs.bottom) { - if (right<rhs.right) { + if (right < rhs.right) { return true; } } @@ -54,8 +53,7 @@ bool Rect::operator < (const Rect& rhs) const return false; } -Rect& Rect::offsetTo(int32_t x, int32_t y) -{ +Rect& Rect::offsetTo(int32_t x, int32_t y) { right -= left - x; bottom -= top - y; left = x; @@ -63,45 +61,41 @@ Rect& Rect::offsetTo(int32_t x, int32_t y) return *this; } -Rect& Rect::offsetBy(int32_t x, int32_t y) -{ +Rect& Rect::offsetBy(int32_t x, int32_t y) { left += x; - top += y; - right+= x; - bottom+=y; + top += y; + right += x; + bottom += y; return *this; } -const Rect Rect::operator + (const Point& rhs) const -{ - const Rect result(left+rhs.x, top+rhs.y, right+rhs.x, bottom+rhs.y); +const Rect Rect::operator +(const Point& rhs) const { + const Rect result(left + rhs.x, top + rhs.y, right + rhs.x, bottom + rhs.y); return result; } -const Rect Rect::operator - (const Point& rhs) const -{ - const Rect result(left-rhs.x, top-rhs.y, right-rhs.x, bottom-rhs.y); +const Rect Rect::operator -(const Point& rhs) const { + const Rect result(left - rhs.x, top - rhs.y, right - rhs.x, bottom - rhs.y); return result; } -bool Rect::intersect(const Rect& with, Rect* result) const -{ - result->left = max(left, with.left); - result->top = max(top, with.top); - result->right = min(right, with.right); - result->bottom = min(bottom, with.bottom); +bool Rect::intersect(const Rect& with, Rect* result) const { + result->left = max(left, with.left); + result->top = max(top, with.top); + result->right = min(right, with.right); + result->bottom = min(bottom, with.bottom); return !(result->isEmpty()); } Rect Rect::transform(uint32_t xform, int32_t width, int32_t height) const { Rect result(*this); if (xform & HAL_TRANSFORM_FLIP_H) { - result = Rect(width - result.right, result.top, - width - result.left, result.bottom); + result = Rect(width - result.right, result.top, width - result.left, + result.bottom); } if (xform & HAL_TRANSFORM_FLIP_V) { - result = Rect(result.left, height - result.bottom, - result.right, height - result.top); + result = Rect(result.left, height - result.bottom, result.right, + height - result.top); } if (xform & HAL_TRANSFORM_ROT_90) { int left = height - result.bottom; @@ -113,4 +107,35 @@ Rect Rect::transform(uint32_t xform, int32_t width, int32_t height) const { return result; } +Rect Rect::reduce(const Rect& exclude) const { + Rect result; + + uint32_t mask = 0; + mask |= (exclude.left > left) ? 1 : 0; + mask |= (exclude.top > top) ? 2 : 0; + mask |= (exclude.right < right) ? 4 : 0; + mask |= (exclude.bottom < bottom) ? 8 : 0; + + if (mask == 0) { + // crop entirely covers us + result.clear(); + } else { + result = *this; + if (!(mask & (mask - 1))) { + // power-of-2, i.e.: just one bit is set + if (mask & 1) { + result.right = exclude.left; + } else if (mask & 2) { + result.bottom = exclude.top; + } else if (mask & 4) { + result.left = exclude.right; + } else if (mask & 8) { + result.top = exclude.bottom; + } + } + } + + return result; +} + }; // namespace android diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index bf01488..e5abcf5 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -697,7 +697,7 @@ void Region::translate(Region& reg, int dx, int dy) size_t count = reg.mStorage.size(); Rect* rects = reg.mStorage.editArray(); while (count) { - rects->translate(dx, dy); + rects->offsetBy(dx, dy); rects++; count--; } @@ -715,14 +715,17 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy) // ---------------------------------------------------------------------------- -size_t Region::getSize() const { +size_t Region::getFlattenedSize() const { return mStorage.size() * sizeof(Rect); } -status_t Region::flatten(void* buffer) const { +status_t Region::flatten(void* buffer, size_t size) const { #if VALIDATE_REGIONS validate(*this, "Region::flatten"); #endif + if (size < mStorage.size() * sizeof(Rect)) { + return NO_MEMORY; + } Rect* rects = reinterpret_cast<Rect*>(buffer); memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect)); return NO_ERROR; diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk index 8b8e1d8..6f62a55 100644 --- a/libs/ui/tests/Android.mk +++ b/libs/ui/tests/Android.mk @@ -4,9 +4,12 @@ include $(CLEAR_VARS) # Build the unit tests. test_src_files := \ - Region_test.cpp + Region_test.cpp \ + vec_test.cpp \ + mat_test.cpp shared_libraries := \ + libutils \ libui static_libraries := \ diff --git a/libs/ui/tests/mat_test.cpp b/libs/ui/tests/mat_test.cpp new file mode 100644 index 0000000..a2c63ac --- /dev/null +++ b/libs/ui/tests/mat_test.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "RegionTest" + +#include <stdlib.h> +#include <ui/Region.h> +#include <ui/Rect.h> +#include <gtest/gtest.h> + +#include <ui/mat4.h> + +namespace android { + +class MatTest : public testing::Test { +protected: +}; + +TEST_F(MatTest, Basics) { + mat4 m0; + EXPECT_EQ(sizeof(mat4), sizeof(float)*16); +} + +TEST_F(MatTest, ComparisonOps) { + mat4 m0; + mat4 m1(2); + + EXPECT_TRUE(m0 == m0); + EXPECT_TRUE(m0 != m1); + EXPECT_FALSE(m0 != m0); + EXPECT_FALSE(m0 == m1); +} + +TEST_F(MatTest, Constructors) { + mat4 m0; + ASSERT_EQ(m0[0].x, 1); + ASSERT_EQ(m0[0].y, 0); + ASSERT_EQ(m0[0].z, 0); + ASSERT_EQ(m0[0].w, 0); + ASSERT_EQ(m0[1].x, 0); + ASSERT_EQ(m0[1].y, 1); + ASSERT_EQ(m0[1].z, 0); + ASSERT_EQ(m0[1].w, 0); + ASSERT_EQ(m0[2].x, 0); + ASSERT_EQ(m0[2].y, 0); + ASSERT_EQ(m0[2].z, 1); + ASSERT_EQ(m0[2].w, 0); + ASSERT_EQ(m0[3].x, 0); + ASSERT_EQ(m0[3].y, 0); + ASSERT_EQ(m0[3].z, 0); + ASSERT_EQ(m0[3].w, 1); + + mat4 m1(2); + mat4 m2(vec4(2)); + mat4 m3(m2); + + EXPECT_EQ(m1, m2); + EXPECT_EQ(m2, m3); + EXPECT_EQ(m3, m1); + + mat4 m4(vec4(1), vec4(2), vec4(3), vec4(4)); +} + +TEST_F(MatTest, ArithmeticOps) { + mat4 m0; + mat4 m1(2); + mat4 m2(vec4(2)); + + m1 += m2; + EXPECT_EQ(mat4(4), m1); + + m2 -= m1; + EXPECT_EQ(mat4(-2), m2); + + m1 *= 2; + EXPECT_EQ(mat4(8), m1); + + m1 /= 2; + EXPECT_EQ(mat4(4), m1); + + m0 = -m0; + EXPECT_EQ(mat4(-1), m0); +} + +TEST_F(MatTest, UnaryOps) { + const mat4 identity; + mat4 m0; + + ++m0; + EXPECT_EQ(mat4( vec4(2,1,1,1), vec4(1,2,1,1), vec4(1,1,2,1), vec4(1,1,1,2) ), m0); + EXPECT_EQ(mat4( -vec4(2,1,1,1), -vec4(1,2,1,1), -vec4(1,1,2,1), -vec4(1,1,1,2) ), -m0); + + --m0; + EXPECT_EQ(identity, m0); +} + +TEST_F(MatTest, MiscOps) { + const mat4 identity; + mat4 m0; + EXPECT_EQ(4, trace(m0)); + + mat4 m1(vec4(1,2,3,4), vec4(5,6,7,8), vec4(9,10,11,12), vec4(13,14,15,16)); + mat4 m2(vec4(1,5,9,13), vec4(2,6,10,14), vec4(3,7,11,15), vec4(4,8,12,16)); + EXPECT_EQ(m1, transpose(m2)); + EXPECT_EQ(m2, transpose(m1)); + EXPECT_EQ(vec4(1,6,11,16), diag(m1)); + + EXPECT_EQ(identity, inverse(identity)); + + mat4 m3(vec4(4,3,0,0), vec4(3,2,0,0), vec4(0,0,1,0), vec4(0,0,0,1)); + mat4 m3i(inverse(m3)); + EXPECT_FLOAT_EQ(-2, m3i[0][0]); + EXPECT_FLOAT_EQ( 3, m3i[0][1]); + EXPECT_FLOAT_EQ( 3, m3i[1][0]); + EXPECT_FLOAT_EQ(-4, m3i[1][1]); + + mat4 m3ii(inverse(m3i)); + EXPECT_FLOAT_EQ(m3[0][0], m3ii[0][0]); + EXPECT_FLOAT_EQ(m3[0][1], m3ii[0][1]); + EXPECT_FLOAT_EQ(m3[1][0], m3ii[1][0]); + EXPECT_FLOAT_EQ(m3[1][1], m3ii[1][1]); + + EXPECT_EQ(m1, m1*identity); +} + +}; // namespace android diff --git a/libs/ui/tests/vec_test.cpp b/libs/ui/tests/vec_test.cpp new file mode 100644 index 0000000..00f737e --- /dev/null +++ b/libs/ui/tests/vec_test.cpp @@ -0,0 +1,256 @@ +/* + * Copyright 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "RegionTest" + +#include <stdlib.h> +#include <ui/Region.h> +#include <ui/Rect.h> +#include <gtest/gtest.h> + +#include <ui/vec4.h> + +namespace android { + +class VecTest : public testing::Test { +protected: +}; + +TEST_F(VecTest, Basics) { + vec4 v4; + vec3& v3(v4.xyz); + + EXPECT_EQ(sizeof(vec4), sizeof(float)*4); + EXPECT_EQ(sizeof(vec3), sizeof(float)*3); + EXPECT_EQ(sizeof(vec2), sizeof(float)*2); + EXPECT_EQ((void*)&v3, (void*)&v4); +} + +TEST_F(VecTest, Constructors) { + vec4 v0; + EXPECT_EQ(v0.x, 0); + EXPECT_EQ(v0.y, 0); + EXPECT_EQ(v0.z, 0); + EXPECT_EQ(v0.w, 0); + + vec4 v1(1); + EXPECT_EQ(v1.x, 1); + EXPECT_EQ(v1.y, 1); + EXPECT_EQ(v1.z, 1); + EXPECT_EQ(v1.w, 1); + + vec4 v2(1,2,3,4); + EXPECT_EQ(v2.x, 1); + EXPECT_EQ(v2.y, 2); + EXPECT_EQ(v2.z, 3); + EXPECT_EQ(v2.w, 4); + + vec4 v3(v2); + EXPECT_EQ(v3.x, 1); + EXPECT_EQ(v3.y, 2); + EXPECT_EQ(v3.z, 3); + EXPECT_EQ(v3.w, 4); + + vec4 v4(v3.xyz, 42); + EXPECT_EQ(v4.x, 1); + EXPECT_EQ(v4.y, 2); + EXPECT_EQ(v4.z, 3); + EXPECT_EQ(v4.w, 42); + + vec4 v5(vec3(v2.xy, 42), 24); + EXPECT_EQ(v5.x, 1); + EXPECT_EQ(v5.y, 2); + EXPECT_EQ(v5.z, 42); + EXPECT_EQ(v5.w, 24); + + tvec4<double> vd(2); + EXPECT_EQ(vd.x, 2); + EXPECT_EQ(vd.y, 2); + EXPECT_EQ(vd.z, 2); + EXPECT_EQ(vd.w, 2); +} + +TEST_F(VecTest, Access) { + vec4 v0(1,2,3,4); + v0.x = 10; + v0.y = 20; + v0.z = 30; + v0.w = 40; + EXPECT_EQ(v0.x, 10); + EXPECT_EQ(v0.y, 20); + EXPECT_EQ(v0.z, 30); + EXPECT_EQ(v0.w, 40); + + v0[0] = 100; + v0[1] = 200; + v0[2] = 300; + v0[3] = 400; + EXPECT_EQ(v0.x, 100); + EXPECT_EQ(v0.y, 200); + EXPECT_EQ(v0.z, 300); + EXPECT_EQ(v0.w, 400); + + v0.xyz = vec3(1,2,3); + EXPECT_EQ(v0.x, 1); + EXPECT_EQ(v0.y, 2); + EXPECT_EQ(v0.z, 3); + EXPECT_EQ(v0.w, 400); +} + +TEST_F(VecTest, UnaryOps) { + vec4 v0(1,2,3,4); + + v0 += 1; + EXPECT_EQ(v0.x, 2); + EXPECT_EQ(v0.y, 3); + EXPECT_EQ(v0.z, 4); + EXPECT_EQ(v0.w, 5); + + v0 -= 1; + EXPECT_EQ(v0.x, 1); + EXPECT_EQ(v0.y, 2); + EXPECT_EQ(v0.z, 3); + EXPECT_EQ(v0.w, 4); + + v0 *= 2; + EXPECT_EQ(v0.x, 2); + EXPECT_EQ(v0.y, 4); + EXPECT_EQ(v0.z, 6); + EXPECT_EQ(v0.w, 8); + + v0 /= 2; + EXPECT_EQ(v0.x, 1); + EXPECT_EQ(v0.y, 2); + EXPECT_EQ(v0.z, 3); + EXPECT_EQ(v0.w, 4); + + vec4 v1(10, 20, 30, 40); + + v0 += v1; + EXPECT_EQ(v0.x, 11); + EXPECT_EQ(v0.y, 22); + EXPECT_EQ(v0.z, 33); + EXPECT_EQ(v0.w, 44); + + v0 -= v1; + EXPECT_EQ(v0.x, 1); + EXPECT_EQ(v0.y, 2); + EXPECT_EQ(v0.z, 3); + EXPECT_EQ(v0.w, 4); + + v0 *= v1; + EXPECT_EQ(v0.x, 10); + EXPECT_EQ(v0.y, 40); + EXPECT_EQ(v0.z, 90); + EXPECT_EQ(v0.w, 160); + + v0 /= v1; + EXPECT_EQ(v0.x, 1); + EXPECT_EQ(v0.y, 2); + EXPECT_EQ(v0.z, 3); + EXPECT_EQ(v0.w, 4); + + ++v0; + EXPECT_EQ(v0.x, 2); + EXPECT_EQ(v0.y, 3); + EXPECT_EQ(v0.z, 4); + EXPECT_EQ(v0.w, 5); + + ++++v0; + EXPECT_EQ(v0.x, 4); + EXPECT_EQ(v0.y, 5); + EXPECT_EQ(v0.z, 6); + EXPECT_EQ(v0.w, 7); + + --v1; + EXPECT_EQ(v1.x, 9); + EXPECT_EQ(v1.y, 19); + EXPECT_EQ(v1.z, 29); + EXPECT_EQ(v1.w, 39); + + v1 = -v1; + EXPECT_EQ(v1.x, -9); + EXPECT_EQ(v1.y, -19); + EXPECT_EQ(v1.z, -29); + EXPECT_EQ(v1.w, -39); + + tvec4<double> dv(1,2,3,4); + v1 += dv; + EXPECT_EQ(v1.x, -8); + EXPECT_EQ(v1.y, -17); + EXPECT_EQ(v1.z, -26); + EXPECT_EQ(v1.w, -35); +} + +TEST_F(VecTest, ComparisonOps) { + vec4 v0(1,2,3,4); + vec4 v1(10,20,30,40); + + EXPECT_TRUE(v0 == v0); + EXPECT_TRUE(v0 != v1); + EXPECT_FALSE(v0 != v0); + EXPECT_FALSE(v0 == v1); +} + +TEST_F(VecTest, ArithmeticOps) { + vec4 v0(1,2,3,4); + vec4 v1(10,20,30,40); + + vec4 v2(v0 + v1); + EXPECT_EQ(v2.x, 11); + EXPECT_EQ(v2.y, 22); + EXPECT_EQ(v2.z, 33); + EXPECT_EQ(v2.w, 44); + + v0 = v1 * 2; + EXPECT_EQ(v0.x, 20); + EXPECT_EQ(v0.y, 40); + EXPECT_EQ(v0.z, 60); + EXPECT_EQ(v0.w, 80); + + v0 = 2 * v1; + EXPECT_EQ(v0.x, 20); + EXPECT_EQ(v0.y, 40); + EXPECT_EQ(v0.z, 60); + EXPECT_EQ(v0.w, 80); + + tvec4<double> vd(2); + v0 = v1 * vd; + EXPECT_EQ(v0.x, 20); + EXPECT_EQ(v0.y, 40); + EXPECT_EQ(v0.z, 60); + EXPECT_EQ(v0.w, 80); +} + +TEST_F(VecTest, ArithmeticFunc) { + vec3 east(1, 0, 0); + vec3 north(0, 1, 0); + vec3 up( cross(east, north) ); + EXPECT_EQ(up, vec3(0,0,1)); + EXPECT_EQ(dot(east, north), 0); + EXPECT_EQ(length(east), 1); + EXPECT_EQ(distance(east, north), sqrtf(2)); + + vec3 v0(1,2,3); + vec3 vn(normalize(v0)); + EXPECT_FLOAT_EQ(1, length(vn)); + EXPECT_FLOAT_EQ(length(v0), dot(v0, vn)); + + tvec3<double> vd(east); + EXPECT_EQ(length(vd), 1); +} + +}; // namespace android |