Minor cleanup
Change-Id: Ic042043c54631b5a5c74d20136addb2c08515ea9
This commit is contained in:
parent
53331da007
commit
f7ae69d4bd
@ -244,9 +244,6 @@ void Layer::setPerFrameData(hwc_layer_t* hwcl) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint16_t pack565(int r, int g, int b) {
|
||||
return (r<<11)|(g<<5)|b;
|
||||
}
|
||||
void Layer::onDraw(const Region& clip) const
|
||||
{
|
||||
if (CC_UNLIKELY(mActiveBuffer == 0)) {
|
||||
@ -260,7 +257,8 @@ void Layer::onDraw(const Region& clip) const
|
||||
|
||||
// figure out if there is something below us
|
||||
Region under;
|
||||
const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
|
||||
const SurfaceFlinger::LayerVector& drawingLayers(
|
||||
mFlinger->mDrawingState.layersSortedByZ);
|
||||
const size_t count = drawingLayers.size();
|
||||
for (size_t i=0 ; i<count ; ++i) {
|
||||
const sp<LayerBase>& layer(drawingLayers[i]);
|
||||
@ -276,7 +274,7 @@ void Layer::onDraw(const Region& clip) const
|
||||
return;
|
||||
}
|
||||
|
||||
GLenum target = mSurfaceTexture->getCurrentTextureTarget();
|
||||
const GLenum target = GL_TEXTURE_EXTERNAL_OES;
|
||||
glBindTexture(target, mTextureName);
|
||||
if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
|
||||
// TODO: we could be more subtle with isFixedSize()
|
||||
@ -439,9 +437,8 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
|
||||
recomputeVisibleRegions = true;
|
||||
}
|
||||
|
||||
const GLenum target(mSurfaceTexture->getCurrentTextureTarget());
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// update the layer size and release freeze-lock
|
||||
const Layer::State& front(drawingState());
|
||||
|
@ -1,341 +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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
#include <GLES/glext.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
|
||||
#include "clz.h"
|
||||
#include "DisplayHardware/DisplayHardware.h"
|
||||
#include "GLExtensions.h"
|
||||
#include "TextureManager.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TextureManager::TextureManager()
|
||||
: mGLExtensions(GLExtensions::getInstance())
|
||||
{
|
||||
}
|
||||
|
||||
GLenum TextureManager::getTextureTarget(const Image* image) {
|
||||
#if defined(GL_OES_EGL_image_external)
|
||||
switch (image->target) {
|
||||
case Texture::TEXTURE_EXTERNAL:
|
||||
return GL_TEXTURE_EXTERNAL_OES;
|
||||
}
|
||||
#endif
|
||||
return GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
status_t TextureManager::initTexture(Texture* texture)
|
||||
{
|
||||
if (texture->name != -1UL)
|
||||
return INVALID_OPERATION;
|
||||
|
||||
GLuint textureName = -1;
|
||||
glGenTextures(1, &textureName);
|
||||
texture->name = textureName;
|
||||
texture->width = 0;
|
||||
texture->height = 0;
|
||||
|
||||
const GLenum target = GL_TEXTURE_2D;
|
||||
glBindTexture(target, textureName);
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t TextureManager::initTexture(Image* pImage, int32_t format)
|
||||
{
|
||||
if (pImage->name != -1UL)
|
||||
return INVALID_OPERATION;
|
||||
|
||||
GLuint textureName = -1;
|
||||
glGenTextures(1, &textureName);
|
||||
pImage->name = textureName;
|
||||
pImage->width = 0;
|
||||
pImage->height = 0;
|
||||
|
||||
GLenum target = GL_TEXTURE_2D;
|
||||
#if defined(GL_OES_EGL_image_external)
|
||||
if (GLExtensions::getInstance().haveTextureExternal()) {
|
||||
if (format && isYuvFormat(format)) {
|
||||
target = GL_TEXTURE_EXTERNAL_OES;
|
||||
pImage->target = Texture::TEXTURE_EXTERNAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindTexture(target, textureName);
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool TextureManager::isSupportedYuvFormat(int format)
|
||||
{
|
||||
switch (format) {
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextureManager::isYuvFormat(int format)
|
||||
{
|
||||
switch (format) {
|
||||
// supported YUV formats
|
||||
case HAL_PIXEL_FORMAT_YV12:
|
||||
// Legacy/deprecated YUV formats
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
|
||||
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
|
||||
case HAL_PIXEL_FORMAT_YCbCr_422_I:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Any OEM format needs to be considered
|
||||
if (format>=0x100 && format<=0x1FF)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
status_t TextureManager::initEglImage(Image* pImage,
|
||||
EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
|
||||
{
|
||||
status_t err = NO_ERROR;
|
||||
if (!pImage->dirty) return err;
|
||||
|
||||
// free the previous image
|
||||
if (pImage->image != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(dpy, pImage->image);
|
||||
pImage->image = EGL_NO_IMAGE_KHR;
|
||||
}
|
||||
|
||||
// construct an EGL_NATIVE_BUFFER_ANDROID
|
||||
ANativeWindowBuffer* clientBuf = buffer->getNativeBuffer();
|
||||
|
||||
// create the new EGLImageKHR
|
||||
const EGLint attrs[] = {
|
||||
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
|
||||
EGL_NONE, EGL_NONE
|
||||
};
|
||||
pImage->image = eglCreateImageKHR(
|
||||
dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||
(EGLClientBuffer)clientBuf, attrs);
|
||||
|
||||
if (pImage->image != EGL_NO_IMAGE_KHR) {
|
||||
if (pImage->name == -1UL) {
|
||||
initTexture(pImage, buffer->format);
|
||||
}
|
||||
const GLenum target = getTextureTarget(pImage);
|
||||
glBindTexture(target, pImage->name);
|
||||
glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image);
|
||||
GLint error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
|
||||
pImage->image, error);
|
||||
err = INVALID_OPERATION;
|
||||
} else {
|
||||
// Everything went okay!
|
||||
pImage->dirty = false;
|
||||
pImage->width = clientBuf->width;
|
||||
pImage->height = clientBuf->height;
|
||||
}
|
||||
} else {
|
||||
LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
|
||||
err = INVALID_OPERATION;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t TextureManager::loadTexture(Texture* texture,
|
||||
const Region& dirty, const GGLSurface& t)
|
||||
{
|
||||
if (texture->name == -1UL) {
|
||||
status_t err = initTexture(texture);
|
||||
LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err));
|
||||
if (err != NO_ERROR) return err;
|
||||
}
|
||||
|
||||
if (texture->target != Texture::TEXTURE_2D)
|
||||
return INVALID_OPERATION;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture->name);
|
||||
|
||||
/*
|
||||
* In OpenGL ES we can't specify a stride with glTexImage2D (however,
|
||||
* GL_UNPACK_ALIGNMENT is a limited form of stride).
|
||||
* So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
|
||||
* need to do something reasonable (here creating a bigger texture).
|
||||
*
|
||||
* extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
|
||||
*
|
||||
* This situation doesn't happen often, but some h/w have a limitation
|
||||
* for their framebuffer (eg: must be multiple of 8 pixels), and
|
||||
* we need to take that into account when using these buffers as
|
||||
* textures.
|
||||
*
|
||||
* This should never be a problem with POT textures
|
||||
*/
|
||||
|
||||
int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
|
||||
unpack = 1 << ((unpack > 3) ? 3 : unpack);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
|
||||
|
||||
/*
|
||||
* round to POT if needed
|
||||
*/
|
||||
if (!mGLExtensions.haveNpot()) {
|
||||
texture->NPOTAdjust = true;
|
||||
}
|
||||
|
||||
if (texture->NPOTAdjust) {
|
||||
// find the smallest power-of-two that will accommodate our surface
|
||||
texture->potWidth = 1 << (31 - clz(t.width));
|
||||
texture->potHeight = 1 << (31 - clz(t.height));
|
||||
if (texture->potWidth < t.width) texture->potWidth <<= 1;
|
||||
if (texture->potHeight < t.height) texture->potHeight <<= 1;
|
||||
texture->wScale = float(t.width) / texture->potWidth;
|
||||
texture->hScale = float(t.height) / texture->potHeight;
|
||||
} else {
|
||||
texture->potWidth = t.width;
|
||||
texture->potHeight = t.height;
|
||||
}
|
||||
|
||||
Rect bounds(dirty.bounds());
|
||||
GLvoid* data = 0;
|
||||
if (texture->width != t.width || texture->height != t.height) {
|
||||
texture->width = t.width;
|
||||
texture->height = t.height;
|
||||
|
||||
// texture size changed, we need to create a new one
|
||||
bounds.set(Rect(t.width, t.height));
|
||||
if (t.width == texture->potWidth &&
|
||||
t.height == texture->potHeight) {
|
||||
// we can do it one pass
|
||||
data = t.data;
|
||||
}
|
||||
|
||||
if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_RGB, texture->potWidth, texture->potHeight, 0,
|
||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
|
||||
} else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_RGBA, texture->potWidth, texture->potHeight, 0,
|
||||
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
|
||||
} else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
|
||||
t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_RGBA, texture->potWidth, texture->potHeight, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else if (isSupportedYuvFormat(t.format)) {
|
||||
// just show the Y plane of YUV buffers
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
// oops, we don't handle this format!
|
||||
LOGE("texture=%d, using format %d, which is not "
|
||||
"supported by the GL", texture->name, t.format);
|
||||
}
|
||||
}
|
||||
if (!data) {
|
||||
if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, bounds.top, t.width, bounds.height(),
|
||||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
||||
t.data + bounds.top*t.stride*2);
|
||||
} else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, bounds.top, t.width, bounds.height(),
|
||||
GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
|
||||
t.data + bounds.top*t.stride*2);
|
||||
} else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
|
||||
t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, bounds.top, t.width, bounds.height(),
|
||||
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
t.data + bounds.top*t.stride*4);
|
||||
} else if (isSupportedYuvFormat(t.format)) {
|
||||
// just show the Y plane of YUV buffers
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
0, bounds.top, t.width, bounds.height(),
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
||||
t.data + bounds.top*t.stride);
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void TextureManager::activateTexture(const Texture& texture, bool filter)
|
||||
{
|
||||
const GLenum target = getTextureTarget(&texture);
|
||||
if (target == GL_TEXTURE_2D) {
|
||||
glBindTexture(GL_TEXTURE_2D, texture.name);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#if defined(GL_OES_EGL_image_external)
|
||||
if (GLExtensions::getInstance().haveTextureExternal()) {
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
}
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.name);
|
||||
glEnable(GL_TEXTURE_EXTERNAL_OES);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureManager::deactivateTextures()
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
#if defined(GL_OES_EGL_image_external)
|
||||
if (GLExtensions::getInstance().haveTextureExternal()) {
|
||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
}; // namespace android
|
@ -1,93 +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 ANDROID_TEXTURE_MANAGER_H
|
||||
#define ANDROID_TEXTURE_MANAGER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES/gl.h>
|
||||
|
||||
#include <ui/Region.h>
|
||||
|
||||
#include <pixelflinger/pixelflinger.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class GLExtensions;
|
||||
class GraphicBuffer;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
struct Image {
|
||||
enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 };
|
||||
Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0),
|
||||
dirty(1), target(TEXTURE_2D) { }
|
||||
GLuint name;
|
||||
EGLImageKHR image;
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
unsigned dirty : 1;
|
||||
unsigned target : 1;
|
||||
};
|
||||
|
||||
struct Texture : public Image {
|
||||
Texture() : Image(), NPOTAdjust(0) { }
|
||||
GLuint potWidth;
|
||||
GLuint potHeight;
|
||||
GLfloat wScale;
|
||||
GLfloat hScale;
|
||||
unsigned NPOTAdjust : 1;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class TextureManager {
|
||||
const GLExtensions& mGLExtensions;
|
||||
static status_t initTexture(Image* texture, int32_t format);
|
||||
static status_t initTexture(Texture* texture);
|
||||
static bool isSupportedYuvFormat(int format);
|
||||
static bool isYuvFormat(int format);
|
||||
static GLenum getTextureTarget(const Image* pImage);
|
||||
public:
|
||||
|
||||
TextureManager();
|
||||
|
||||
// load bitmap data into the active buffer
|
||||
status_t loadTexture(Texture* texture,
|
||||
const Region& dirty, const GGLSurface& t);
|
||||
|
||||
// make active buffer an EGLImage if needed
|
||||
status_t initEglImage(Image* texture,
|
||||
EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
|
||||
|
||||
// activate a texture
|
||||
static void activateTexture(const Texture& texture, bool filter);
|
||||
|
||||
// deactivate a texture
|
||||
static void deactivateTextures();
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_TEXTURE_MANAGER_H
|
Loading…
Reference in New Issue
Block a user