Merge "Fix multicast API"
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index 37a9b4a..bc630ae 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -78,7 +78,12 @@
// client for this buffer. The timestamp is measured in nanoseconds, and
// must be monotonically increasing. Its other properties (zero point, etc)
// are client-dependent, and should be documented by the client.
- virtual status_t queueBuffer(int slot, int64_t timestamp) = 0;
+ //
+ // outWidth, outHeight and outTransform are filled with the default width
+ // and height of the window and current transform applied to buffers,
+ // respectively.
+ virtual status_t queueBuffer(int slot, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
// cancelBuffer indicates that the client does not wish to fill in the
// buffer associated with slot and transfers ownership of the slot back to
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index e46765e..945f4bc 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -84,7 +84,8 @@
// nanoseconds, and must be monotonically increasing. Its other semantics
// (zero point, etc) are client-dependent and should be documented by the
// client.
- virtual status_t queueBuffer(int buf, int64_t timestamp);
+ virtual status_t queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
virtual void cancelBuffer(int buf);
virtual status_t setCrop(const Rect& reg);
virtual status_t setTransform(uint32_t transform);
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 76e7119..829d8ab 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -151,6 +151,18 @@
// dequeued format or to mReqFormat if no buffer was dequeued.
uint32_t mQueryFormat;
+ // mDefaultWidth is default width of the window, regardless of the
+ // set_dimension call
+ uint32_t mDefaultWidth;
+
+ // mDefaultHeight is default width of the window, regardless of the
+ // set_dimension call
+ uint32_t mDefaultHeight;
+
+ // mTransformHint is the transform probably applied to buffers of this
+ // window. this is only a hint, actual transform may differ.
+ uint32_t mTransformHint;
+
// mMutex is the mutex used to prevent concurrent access to the member
// variables of SurfaceTexture objects. It must be locked whenever the
// member variables are accessed.
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
index 6e9a654..02cabc1 100644
--- a/include/surfaceflinger/ISurfaceComposerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -45,9 +45,6 @@
struct surface_data_t {
int32_t token;
int32_t identity;
- uint32_t width;
- uint32_t height;
- uint32_t format;
status_t readFromParcel(const Parcel& parcel);
status_t writeToParcel(Parcel* parcel) const;
};
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index c2a494d..9c352ad 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -57,7 +57,6 @@
static bool isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
- uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
// release surface data from java
@@ -86,25 +85,13 @@
SurfaceControl& operator = (SurfaceControl& rhs);
SurfaceControl(const SurfaceControl& rhs);
-
friend class SurfaceComposerClient;
-
- // camera and camcorder need access to the ISurface binder interface for preview
- friend class CameraService;
- friend class MediaRecorder;
- // mediaplayer needs access to ISurface for display
- friend class MediaPlayer;
- // for testing
- friend class Test;
- // videoEditor preview classes
- friend class VideoEditorPreviewController;
friend class Surface;
SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+ const ISurfaceComposerClient::surface_data_t& data);
~SurfaceControl();
@@ -115,10 +102,6 @@
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
- uint32_t mWidth;
- uint32_t mHeight;
- PixelFormat mFormat;
- uint32_t mFlags;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
@@ -139,17 +122,13 @@
uint32_t reserved[2];
};
- static status_t writeToParcel(
- const sp<Surface>& control, Parcel* parcel);
-
+ static status_t writeToParcel(const sp<Surface>& control, Parcel* parcel);
static sp<Surface> readFromParcel(const Parcel& data);
-
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
}
bool isValid();
- uint32_t getFlags() const { return mFlags; }
uint32_t getIdentity() const { return mIdentity; }
sp<ISurfaceTexture> getSurfaceTexture();
@@ -176,22 +155,14 @@
* private stuff...
*/
void init();
- status_t validate(bool inCancelBuffer = false) const;
static void cleanCachedSurfacesLocked();
virtual int query(int what, int* value) const;
// constants
- status_t mInitCheck;
sp<ISurface> mSurface;
uint32_t mIdentity;
- PixelFormat mFormat;
- uint32_t mFlags;
-
- // query() must be called from dequeueBuffer() thread
- uint32_t mWidth;
- uint32_t mHeight;
// A cache of Surface objects that have been deserialized into this process.
static Mutex sCachedSurfacesLock;
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
deleted file mode 100644
index 2ee768e..0000000
--- a/include/utils/Pool.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef UTILS_POOL_H
-#define UTILS_POOL_H
-
-#include <utils/TypeHelpers.h>
-
-namespace android {
-
-class PoolImpl {
-public:
- PoolImpl(size_t objSize);
- ~PoolImpl();
-
- void* allocImpl();
- void freeImpl(void* obj);
-
-private:
- size_t mObjSize;
-};
-
-/*
- * A homogeneous typed memory pool for fixed size objects.
- * Not intended to be thread-safe.
- */
-template<typename T>
-class Pool : private PoolImpl {
-public:
- /* Creates an initially empty pool. */
- Pool() : PoolImpl(sizeof(T)) { }
-
- /* Destroys the pool.
- * Assumes that the pool is empty. */
- ~Pool() { }
-
- /* Allocates an object from the pool, growing the pool if needed. */
- inline T* alloc() {
- void* mem = allocImpl();
- if (! traits<T>::has_trivial_ctor) {
- return new (mem) T();
- } else {
- return static_cast<T*>(mem);
- }
- }
-
- /* Frees an object from the pool. */
- inline void free(T* obj) {
- if (! traits<T>::has_trivial_dtor) {
- obj->~T();
- }
- freeImpl(obj);
- }
-};
-
-} // namespace android
-
-#endif // UTILS_POOL_H
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index bc97cac..ace16aa 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -132,9 +132,6 @@
{
token = parcel.readInt32();
identity = parcel.readInt32();
- width = parcel.readInt32();
- height = parcel.readInt32();
- format = parcel.readInt32();
return NO_ERROR;
}
@@ -142,9 +139,6 @@
{
parcel->writeInt32(token);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
return NO_ERROR;
}
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index b4b7492..be90e2e 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -93,12 +93,16 @@
return result;
}
- virtual status_t queueBuffer(int buf, int64_t timestamp) {
+ virtual status_t queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
data.writeInt32(buf);
data.writeInt64(timestamp);
remote()->transact(QUEUE_BUFFER, data, &reply);
+ *outWidth = reply.readInt32();
+ *outHeight = reply.readInt32();
+ *outTransform = reply.readInt32();
status_t result = reply.readInt32();
return result;
}
@@ -226,7 +230,12 @@
CHECK_INTERFACE(ISurfaceTexture, data, reply);
int buf = data.readInt32();
int64_t timestamp = data.readInt64();
- status_t result = queueBuffer(buf, timestamp);
+ uint32_t outWidth, outHeight, outTransform;
+ status_t result = queueBuffer(buf, timestamp,
+ &outWidth, &outHeight, &outTransform);
+ reply->writeInt32(outWidth);
+ reply->writeInt32(outHeight);
+ reply->writeInt32(outTransform);
reply->writeInt32(result);
return NO_ERROR;
} break;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index dabe643..c4f9e53 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -26,15 +26,12 @@
#include <utils/Log.h>
#include <utils/threads.h>
-#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <gui/SurfaceTextureClient.h>
#include <ui/DisplayInfo.h>
#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-#include <ui/GraphicLog.h>
#include <ui/Rect.h>
#include <surfaceflinger/ISurface.h>
@@ -42,8 +39,6 @@
#include <surfaceflinger/Surface.h>
#include <surfaceflinger/SurfaceComposerClient.h>
-#include <private/surfaceflinger/LayerState.h>
-
namespace android {
// ============================================================================
@@ -53,12 +48,9 @@
SurfaceControl::SurfaceControl(
const sp<SurfaceComposerClient>& client,
const sp<ISurface>& surface,
- const ISurfaceComposerClient::surface_data_t& data,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+ const ISurfaceComposerClient::surface_data_t& data)
: mClient(client), mSurface(surface),
- mToken(data.token), mIdentity(data.identity),
- mWidth(data.width), mHeight(data.height), mFormat(data.format),
- mFlags(flags)
+ mToken(data.token), mIdentity(data.identity)
{
}
@@ -187,24 +179,12 @@
{
sp<ISurface> sur;
uint32_t identity = 0;
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t format = 0;
- uint32_t flags = 0;
if (SurfaceControl::isValid(control)) {
sur = control->mSurface;
identity = control->mIdentity;
- width = control->mWidth;
- height = control->mHeight;
- format = control->mFormat;
- flags = control->mFlags;
}
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
- parcel->writeInt32(flags);
return NO_ERROR;
}
@@ -225,25 +205,17 @@
Surface::Surface(const sp<SurfaceControl>& surface)
: SurfaceTextureClient(),
- mInitCheck(NO_INIT),
mSurface(surface->mSurface),
- mIdentity(surface->mIdentity),
- mFormat(surface->mFormat), mFlags(surface->mFlags),
- mWidth(surface->mWidth), mHeight(surface->mHeight)
+ mIdentity(surface->mIdentity)
{
init();
}
Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
- : SurfaceTextureClient(),
- mInitCheck(NO_INIT)
+ : SurfaceTextureClient()
{
mSurface = interface_cast<ISurface>(ref);
mIdentity = parcel.readInt32();
- mWidth = parcel.readInt32();
- mHeight = parcel.readInt32();
- mFormat = parcel.readInt32();
- mFlags = parcel.readInt32();
init();
}
@@ -252,31 +224,16 @@
{
sp<ISurface> sur;
uint32_t identity = 0;
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t format = 0;
- uint32_t flags = 0;
if (Surface::isValid(surface)) {
sur = surface->mSurface;
identity = surface->mIdentity;
- width = surface->mWidth;
- height = surface->mHeight;
- format = surface->mFormat;
- flags = surface->mFlags;
} else if (surface != 0 && surface->mSurface != 0) {
LOGW("Parceling invalid surface with non-NULL ISurface as NULL: "
- "mSurface = %p, mIdentity = %d, mWidth = %d, mHeight = %d, "
- "mFormat = %d, mFlags = 0x%08x, mInitCheck = %d",
- surface->mSurface.get(), surface->mIdentity, surface->mWidth,
- surface->mHeight, surface->mFormat, surface->mFlags,
- surface->mInitCheck);
+ "mSurface = %p, mIdentity = %d",
+ surface->mSurface.get(), surface->mIdentity);
}
parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
parcel->writeInt32(identity);
- parcel->writeInt32(width);
- parcel->writeInt32(height);
- parcel->writeInt32(format);
- parcel->writeInt32(flags);
return NO_ERROR;
}
@@ -325,10 +282,6 @@
const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
const_cast<uint32_t&>(ANativeWindow::flags) = 0;
-
- if (surfaceTexture != NULL) {
- mInitCheck = NO_ERROR;
- }
}
}
@@ -341,21 +294,11 @@
}
bool Surface::isValid() {
- return mInitCheck == NO_ERROR;
-}
-
-status_t Surface::validate(bool inCancelBuffer) const
-{
- // check that we initialized ourself properly
- if (mInitCheck != NO_ERROR) {
- LOGE("invalid token (identity=%u)", mIdentity);
- return mInitCheck;
- }
- return NO_ERROR;
+ return getISurfaceTexture() != NULL;
}
sp<ISurfaceTexture> Surface::getSurfaceTexture() {
- return mSurface != NULL ? mSurface->getSurfaceTexture() : NULL;
+ return getISurfaceTexture();
}
sp<IBinder> Surface::asBinder() const {
@@ -367,7 +310,6 @@
int Surface::query(int what, int* value) const {
switch (what) {
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- // TODO: this is not needed anymore
*value = 1;
return NO_ERROR;
case NATIVE_WINDOW_CONCRETE_TYPE:
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8cead80..3b0ffea 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -339,7 +339,7 @@
sp<ISurface> surface = mClient->createSurface(&data, name,
display, w, h, format, flags);
if (surface != 0) {
- result = new SurfaceControl(this, surface, data, w, h, format, flags);
+ result = new SurfaceControl(this, surface, data);
}
}
return result;
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3ab6c79..0f08570 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -402,7 +402,8 @@
return err;
}
-status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
+status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
LOGV("SurfaceTexture::queueBuffer");
sp<FrameAvailableListener> listener;
@@ -463,6 +464,11 @@
if (listener != 0) {
listener->onFrameAvailable();
}
+
+ *outWidth = mDefaultWidth;
+ *outHeight = mDefaultHeight;
+ *outTransform = 0;
+
return OK;
}
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 68475e9..1dc6cd2 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -222,26 +222,38 @@
if (i < 0) {
return i;
}
- mSurfaceTexture->queueBuffer(i, timestamp);
+ mSurfaceTexture->queueBuffer(i, timestamp,
+ &mDefaultWidth, &mDefaultHeight, &mTransformHint);
return OK;
}
int SurfaceTextureClient::query(int what, int* value) const {
LOGV("SurfaceTextureClient::query");
- switch (what) {
- case NATIVE_WINDOW_FORMAT:
- if (mReqFormat) {
- *value = mReqFormat;
- return NO_ERROR;
+ { // scope for the lock
+ Mutex::Autolock lock(mMutex);
+ switch (what) {
+ case NATIVE_WINDOW_FORMAT:
+ if (mReqFormat) {
+ *value = mReqFormat;
+ return NO_ERROR;
+ }
+ break;
+ case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+ *value = 0;
+ return NO_ERROR;
+ case NATIVE_WINDOW_CONCRETE_TYPE:
+ *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
+ return NO_ERROR;
+ case NATIVE_WINDOW_DEFAULT_WIDTH:
+ *value = mDefaultWidth;
+ return NO_ERROR;
+ case NATIVE_WINDOW_DEFAULT_HEIGHT:
+ *value = mDefaultHeight;
+ return NO_ERROR;
+ case NATIVE_WINDOW_TRANSFORM_HINT:
+ *value = mTransformHint;
+ return NO_ERROR;
}
- break;
- case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
- // TODO: this is not needed anymore
- *value = 0;
- return NO_ERROR;
- case NATIVE_WINDOW_CONCRETE_TYPE:
- *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
- return NO_ERROR;
}
return mSurfaceTexture->query(what, value);
}
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 2b8f204..c1a3c98 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -116,11 +116,6 @@
EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
}
-TEST_F(SurfaceTextureClientTest, ANativeWindowLockFails) {
- ANativeWindow_Buffer buf;
- ASSERT_EQ(BAD_VALUE, ANativeWindow_lock(mANW.get(), &buf, NULL));
-}
-
TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
ASSERT_EQ(EGL_SUCCESS, eglGetError());
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index e2772a7..412552e 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -289,6 +289,18 @@
case NATIVE_WINDOW_CONCRETE_TYPE:
*value = NATIVE_WINDOW_FRAMEBUFFER;
return NO_ERROR;
+ case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+ *value = 0;
+ return NO_ERROR;
+ case NATIVE_WINDOW_DEFAULT_WIDTH:
+ *value = fb->width;
+ return NO_ERROR;
+ case NATIVE_WINDOW_DEFAULT_HEIGHT:
+ *value = fb->height;
+ return NO_ERROR;
+ case NATIVE_WINDOW_TRANSFORM_HINT:
+ *value = 0;
+ return NO_ERROR;
}
*value = 0;
return BAD_VALUE;
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index f633357..e4eadbd 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -29,7 +29,6 @@
Flattenable.cpp \
LinearTransform.cpp \
ObbFile.cpp \
- Pool.cpp \
PropertyMap.cpp \
RefBase.cpp \
ResourceTypes.cpp \
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
deleted file mode 100644
index 8f18cb9..0000000
--- a/libs/utils/Pool.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright 2010 The Android Open Source Project
-//
-// A simple memory pool.
-//
-#define LOG_TAG "Pool"
-
-//#define LOG_NDEBUG 0
-
-#include <cutils/log.h>
-#include <utils/Pool.h>
-
-#include <stdlib.h>
-
-namespace android {
-
-// TODO Provide a real implementation of a pool. This is just a stub for initial development.
-
-PoolImpl::PoolImpl(size_t objSize) :
- mObjSize(objSize) {
-}
-
-PoolImpl::~PoolImpl() {
-}
-
-void* PoolImpl::allocImpl() {
- void* ptr = malloc(mObjSize);
- LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
- return ptr;
-}
-
-void PoolImpl::freeImpl(void* obj) {
- LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
- return free(obj);
-}
-
-} // namespace android
diff --git a/opengl/tests/gl2_copyTexImage/Android.mk b/opengl/tests/gl2_copyTexImage/Android.mk
new file mode 100644
index 0000000..bef1f90
--- /dev/null
+++ b/opengl/tests/gl2_copyTexImage/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ gl2_copyTexImage.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libEGL \
+ libGLESv2 \
+ libui
+
+LOCAL_MODULE:= test-opengl-gl2_copyTexImage
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
new file mode 100644
index 0000000..c2bfdec
--- /dev/null
+++ b/opengl/tests/gl2_copyTexImage/gl2_copyTexImage.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <utils/Timers.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+static void printGLString(const char *name, GLenum s) {
+ // fprintf(stderr, "printGLString %s, %d\n", name, s);
+ const char *v = (const char *) glGetString(s);
+ // int error = glGetError();
+ // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+ // (unsigned int) v);
+ // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+ // fprintf(stderr, "GL %s = %s\n", name, v);
+ // else
+ // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+ fprintf(stderr, "GL %s = %s\n", name, v);
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+ if (returnVal != EGL_TRUE) {
+ fprintf(stderr, "%s() returned %d\n", op, returnVal);
+ }
+
+ for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+ = eglGetError()) {
+ fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+ error);
+ }
+}
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+ }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.5);\n"
+ "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
+ shaderType, buf);
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ fprintf(stderr, "Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+GLuint gProgram;
+GLuint gTextureProgram;
+GLuint gvPositionHandle;
+GLuint gvTexturePositionHandle;
+GLuint gvTextureTexCoordsHandle;
+GLuint gvTextureSamplerHandle;
+GLuint gFbo;
+GLuint gTexture;
+GLuint gBufferTexture;
+
+static const char gSimpleVS[] =
+ "attribute vec4 position;\n"
+ "attribute vec2 texCoords;\n"
+ "varying vec2 outTexCoords;\n"
+ "\nvoid main(void) {\n"
+ " outTexCoords = texCoords;\n"
+ " gl_Position = position;\n"
+ "}\n\n";
+static const char gSimpleFS[] =
+ "precision mediump float;\n\n"
+ "varying vec2 outTexCoords;\n"
+ "uniform sampler2D texture;\n"
+ "\nvoid main(void) {\n"
+ " gl_FragColor = texture2D(texture, outTexCoords);\n"
+ "}\n\n";
+
+bool setupGraphics(int w, int h) {
+ gProgram = createProgram(gVertexShader, gFragmentShader);
+ if (!gProgram) {
+ return false;
+ }
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n", gvPositionHandle);
+
+ gTextureProgram = createProgram(gSimpleVS, gSimpleFS);
+ if (!gTextureProgram) {
+ return false;
+ }
+ gvTexturePositionHandle = glGetAttribLocation(gTextureProgram, "position");
+ checkGlError("glGetAttribLocation");
+ gvTextureTexCoordsHandle = glGetAttribLocation(gTextureProgram, "texCoords");
+ checkGlError("glGetAttribLocation");
+ gvTextureSamplerHandle = glGetUniformLocation(gTextureProgram, "texture");
+ checkGlError("glGetAttribLocation");
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenTextures(1, &gTexture);
+ glBindTexture(GL_TEXTURE_2D, gTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glGenTextures(1, &gBufferTexture);
+ glBindTexture(GL_TEXTURE_2D, gBufferTexture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glGenFramebuffers(1, &gFbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, gFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gTexture, 0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+ return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+const GLint FLOAT_SIZE_BYTES = 4;
+const GLint TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
+const GLfloat gTriangleVerticesData[] = {
+ // X, Y, Z, U, V
+ -1.0f, -1.0f, 0, 0.f, 0.f,
+ 1.0f, -1.0f, 0, 1.f, 0.f,
+ -1.0f, 1.0f, 0, 0.f, 1.f,
+ 1.0f, 1.0f, 0, 1.f, 1.f,
+};
+
+void renderFrame(GLint w, GLint h) {
+ glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+ checkGlError("glClearColor");
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ // Bind FBO and draw into it
+ glBindFramebuffer(GL_FRAMEBUFFER, gFbo);
+ checkGlError("glBindFramebuffer");
+
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ checkGlError("glClearColor");
+ glClear(GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+
+ // Copy content of FBO into a texture
+ glBindTexture(GL_TEXTURE_2D, gBufferTexture);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w / 2, h / 2);
+ checkGlError("glCopyTexSubImage2D");
+
+ // Back to the display
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ checkGlError("glBindFramebuffer");
+
+ // Draw copied content on the screen
+ glUseProgram(gTextureProgram);
+ checkGlError("glUseProgram");
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ glVertexAttribPointer(gvTexturePositionHandle, 3, GL_FLOAT, GL_FALSE,
+ TRIANGLE_VERTICES_DATA_STRIDE_BYTES, gTriangleVerticesData);
+ checkGlError("glVertexAttribPointer");
+ glVertexAttribPointer(gvTextureTexCoordsHandle, 2, GL_FLOAT, GL_FALSE,
+ TRIANGLE_VERTICES_DATA_STRIDE_BYTES, &gTriangleVerticesData[3]);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvTexturePositionHandle);
+ glEnableVertexAttribArray(gvTextureTexCoordsHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ checkGlError("glDrawArrays");
+}
+
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+ struct {EGLint attribute; const char* name;} names[] = {
+ X(EGL_BUFFER_SIZE),
+ X(EGL_ALPHA_SIZE),
+ X(EGL_BLUE_SIZE),
+ X(EGL_GREEN_SIZE),
+ X(EGL_RED_SIZE),
+ X(EGL_DEPTH_SIZE),
+ X(EGL_STENCIL_SIZE),
+ X(EGL_CONFIG_CAVEAT),
+ X(EGL_CONFIG_ID),
+ X(EGL_LEVEL),
+ X(EGL_MAX_PBUFFER_HEIGHT),
+ X(EGL_MAX_PBUFFER_PIXELS),
+ X(EGL_MAX_PBUFFER_WIDTH),
+ X(EGL_NATIVE_RENDERABLE),
+ X(EGL_NATIVE_VISUAL_ID),
+ X(EGL_NATIVE_VISUAL_TYPE),
+ X(EGL_SAMPLES),
+ X(EGL_SAMPLE_BUFFERS),
+ X(EGL_SURFACE_TYPE),
+ X(EGL_TRANSPARENT_TYPE),
+ X(EGL_TRANSPARENT_RED_VALUE),
+ X(EGL_TRANSPARENT_GREEN_VALUE),
+ X(EGL_TRANSPARENT_BLUE_VALUE),
+ X(EGL_BIND_TO_TEXTURE_RGB),
+ X(EGL_BIND_TO_TEXTURE_RGBA),
+ X(EGL_MIN_SWAP_INTERVAL),
+ X(EGL_MAX_SWAP_INTERVAL),
+ X(EGL_LUMINANCE_SIZE),
+ X(EGL_ALPHA_MASK_SIZE),
+ X(EGL_COLOR_BUFFER_TYPE),
+ X(EGL_RENDERABLE_TYPE),
+ X(EGL_CONFORMANT),
+ };
+#undef X
+
+ for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+ EGLint value = -1;
+ EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+ EGLint error = eglGetError();
+ if (returnVal && error == EGL_SUCCESS) {
+ printf(" %s: ", names[j].name);
+ printf("%d (0x%x)", value, value);
+ }
+ }
+ printf("\n");
+}
+
+int printEGLConfigurations(EGLDisplay dpy) {
+ EGLint numConfig = 0;
+ EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
+ checkEglError("eglGetConfigs", returnVal);
+ if (!returnVal) {
+ return false;
+ }
+
+ printf("Number of EGL configuration: %d\n", numConfig);
+
+ EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
+ if (! configs) {
+ printf("Could not allocate configs.\n");
+ return false;
+ }
+
+ returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
+ checkEglError("eglGetConfigs", returnVal);
+ if (!returnVal) {
+ free(configs);
+ return false;
+ }
+
+ for(int i = 0; i < numConfig; i++) {
+ printf("Configuration %d\n", i);
+ printEGLConfiguration(dpy, configs[i]);
+ }
+
+ free(configs);
+ return true;
+}
+
+int main(int argc, char** argv) {
+ EGLBoolean returnValue;
+ EGLConfig myConfig = {0};
+
+ EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ EGLint s_configAttribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_NONE };
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLContext context;
+ EGLSurface surface;
+ EGLint w, h;
+
+ EGLDisplay dpy;
+
+ checkEglError("<init>");
+ dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ checkEglError("eglGetDisplay");
+ if (dpy == EGL_NO_DISPLAY) {
+ printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+ return 0;
+ }
+
+ returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+ checkEglError("eglInitialize", returnValue);
+ fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+ if (returnValue != EGL_TRUE) {
+ printf("eglInitialize failed\n");
+ return 0;
+ }
+
+ if (!printEGLConfigurations(dpy)) {
+ printf("printEGLConfigurations failed\n");
+ return 0;
+ }
+
+ checkEglError("printEGLConfigurations");
+
+ EGLNativeWindowType window = android_createDisplaySurface();
+ EGLint numConfigs = -1, n = 0;
+ eglChooseConfig(dpy, s_configAttribs, 0, 0, &numConfigs);
+ if (numConfigs) {
+ EGLConfig* const configs = new EGLConfig[numConfigs];
+ eglChooseConfig(dpy, s_configAttribs, configs, numConfigs, &n);
+ myConfig = configs[0];
+ delete[] configs;
+ }
+
+ checkEglError("EGLUtils::selectConfigForNativeWindow");
+
+ printf("Chose this configuration:\n");
+ printEGLConfiguration(dpy, myConfig);
+
+ surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (surface == EGL_NO_SURFACE) {
+ printf("gelCreateWindowSurface failed.\n");
+ return 0;
+ }
+
+ context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
+ checkEglError("eglCreateContext");
+ if (context == EGL_NO_CONTEXT) {
+ printf("eglCreateContext failed\n");
+ return 0;
+ }
+ returnValue = eglMakeCurrent(dpy, surface, surface, context);
+ checkEglError("eglMakeCurrent", returnValue);
+ if (returnValue != EGL_TRUE) {
+ return 0;
+ }
+ eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+ checkEglError("eglQuerySurface");
+ eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+ checkEglError("eglQuerySurface");
+ GLint dim = w < h ? w : h;
+
+ fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
+
+ if(!setupGraphics(w, h)) {
+ fprintf(stderr, "Could not set up graphics.\n");
+ return 0;
+ }
+
+ for (;;) {
+ renderFrame(w, h);
+ eglSwapBuffers(dpy, surface);
+ checkEglError("eglSwapBuffers");
+ }
+
+ return 0;
+}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c29aeca..e0268fa 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -44,10 +44,6 @@
namespace android {
-template <typename T> inline T min(T a, T b) {
- return a<b ? a : b;
-}
-
// ---------------------------------------------------------------------------
Layer::Layer(SurfaceFlinger* flinger,
@@ -457,13 +453,22 @@
// FIXME: mPostedDirtyRegion = dirty & bounds
mPostedDirtyRegion.set(front.w, front.h);
- sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
- if ((newFrontBuffer->getWidth() == front.requested_w &&
- newFrontBuffer->getHeight() == front.requested_h) ||
- isFixedSize())
+
+ if ((front.w != front.requested_w) ||
+ (front.h != front.requested_h))
{
- if ((front.w != front.requested_w) ||
- (front.h != front.requested_h))
+ // check that we received a buffer of the right size
+ // (Take the buffer's orientation into account)
+ sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
+ uint32_t bufWidth = newFrontBuffer->getWidth();
+ uint32_t bufHeight = newFrontBuffer->getHeight();
+ if (mCurrentTransform & Transform::ROT_90) {
+ swap(bufWidth, bufHeight);
+ }
+
+ if (isFixedSize() ||
+ (bufWidth == front.requested_w &&
+ bufHeight == front.requested_h))
{
// Here we pretend the transaction happened by updating the
// current and drawing states. Drawing state is only accessed
@@ -483,10 +488,10 @@
// recompute visible region
recomputeVisibleRegions = true;
- }
- // we now have the correct size, unfreeze the screen
- mFreezeLock.clear();
+ // we now have the correct size, unfreeze the screen
+ mFreezeLock.clear();
+ }
}
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 680814c..4a27701 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1318,9 +1318,6 @@
if (surfaceHandle != 0) {
params->token = token;
params->identity = layer->getIdentity();
- params->width = w;
- params->height = h;
- params->format = format;
if (normalLayer != 0) {
Mutex::Autolock _l(mStateLock);
mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index a586d59..11f61cc 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -52,6 +52,20 @@
return res;
}
+status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
+
+ status_t res = SurfaceTexture::queueBuffer(buf, timestamp,
+ outWidth, outHeight, outTransform);
+
+ sp<Layer> layer(mLayer.promote());
+ if (layer != NULL) {
+ *outTransform = layer->getOrientation();
+ }
+
+ return res;
+}
+
status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h
index 7faff54..29a9cbe 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.h
+++ b/services/surfaceflinger/SurfaceTextureLayer.h
@@ -45,6 +45,9 @@
virtual status_t setBufferCount(int bufferCount);
protected:
+ virtual status_t queueBuffer(int buf, int64_t timestamp,
+ uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
+
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage);
};
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index 4cedcbf..24d5f9a 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -20,6 +20,7 @@
#include <utils/String8.h>
#include <ui/Region.h>
+#include "clz.h"
#include "Transform.h"
// ---------------------------------------------------------------------------
@@ -28,42 +29,6 @@
// ---------------------------------------------------------------------------
-template <typename T>
-static inline T min(T a, T b) {
- return a<b ? a : b;
-}
-template <typename T>
-static inline T min(T a, T b, T c) {
- return min(a, min(b, c));
-}
-template <typename T>
-static inline T min(T a, T b, T c, T d) {
- return min(a, b, min(c, d));
-}
-
-template <typename T>
-static inline T max(T a, T b) {
- return a>b ? a : b;
-}
-template <typename T>
-static inline T max(T a, T b, T c) {
- return max(a, max(b, c));
-}
-template <typename T>
-static inline T max(T a, T b, T c, T d) {
- return max(a, b, max(c, d));
-}
-
-template <typename T>
-static inline
-void swap(T& a, T& b) {
- T t(a);
- a = b;
- b = t;
-}
-
-// ---------------------------------------------------------------------------
-
Transform::Transform() {
reset();
}
diff --git a/services/surfaceflinger/clz.h b/services/surfaceflinger/clz.h
index ca44555..a4c5262 100644
--- a/services/surfaceflinger/clz.h
+++ b/services/surfaceflinger/clz.h
@@ -24,6 +24,41 @@
return __builtin_clz(x);
}
+template <typename T>
+static inline T min(T a, T b) {
+ return a<b ? a : b;
+}
+template <typename T>
+static inline T min(T a, T b, T c) {
+ return min(a, min(b, c));
+}
+template <typename T>
+static inline T min(T a, T b, T c, T d) {
+ return min(a, b, min(c, d));
+}
+
+template <typename T>
+static inline T max(T a, T b) {
+ return a>b ? a : b;
+}
+template <typename T>
+static inline T max(T a, T b, T c) {
+ return max(a, max(b, c));
+}
+template <typename T>
+static inline T max(T a, T b, T c, T d) {
+ return max(a, b, max(c, d));
+}
+
+template <typename T>
+static inline
+void swap(T& a, T& b) {
+ T t(a);
+ a = b;
+ b = t;
+}
+
+
}; // namespace android
#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */