eDisplayIdHdmi = 1
};
+ enum Rotation {
+ eRotateNone = 0,
+ eRotate90 = 1,
+ eRotate180 = 2,
+ eRotate270 = 3
+ };
+
/* create connection with surface flinger, requires
* ACCESS_SURFACE_FLINGER permission
*/
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) = 0;
+ bool useIdentityTransform,
+ Rotation rotation = eRotateNone) = 0;
/* Clears the frame statistics for animations.
*
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform,
+ ISurfaceComposer::Rotation rotation)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeInt32(minLayerZ);
data.writeInt32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
+ data.writeInt32(static_cast<int32_t>(rotation));
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
return reply.readInt32();
}
uint32_t minLayerZ = data.readInt32();
uint32_t maxLayerZ = data.readInt32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
+ uint32_t rotation = data.readInt32();
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform,
+ static_cast<ISurfaceComposer::Rotation>(rotation));
reply->writeInt32(res);
return NO_ERROR;
}
size_t w = mDisplayWidth;
size_t h = mDisplayHeight;
Rect sourceCrop(0, 0, w, h);
- mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, false);
+ mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
+ false, Transform::ROT_0);
}
// ----------------------------------------------------------------------------
#include <utils/String8.h>
#include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
#include "GLES11RenderEngine.h"
#include "Mesh.h"
}
void GLES11RenderEngine::setViewportAndProjection(
- size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+ size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+ Transform::orientation_flags rotation) {
glViewport(0, 0, vpw, vph);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
} else {
glOrthof(l, r, b, t, 0, 1);
}
+
+ switch (rotation) {
+ case Transform::ROT_0:
+ break;
+ case Transform::ROT_90:
+ glRotatef(90, 0, 0, 1);
+ break;
+ case Transform::ROT_180:
+ glRotatef(180, 0, 0, 1);
+ break;
+ case Transform::ROT_270:
+ glRotatef(270, 0, 0, 1);
+ break;
+ default:
+ break;
+ }
+
glMatrixMode(GL_MODELVIEW);
}
#include <sys/types.h>
#include <GLES/gl.h>
+#include <Transform.h>
#include "RenderEngine.h"
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap);
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
virtual void setupDimLayerBlending(int alpha);
virtual void setupLayerTexturing(const Texture& texture);
#include <utils/Trace.h>
#include <cutils/compiler.h>
+#include <gui/ISurfaceComposer.h>
+#include <math.h>
#include "GLES20RenderEngine.h"
#include "Program.h"
}
void GLES20RenderEngine::setViewportAndProjection(
- size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) {
+ size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
+ Transform::orientation_flags rotation) {
size_t l = sourceCrop.left;
size_t r = sourceCrop.right;
m = mat4::ortho(l, r, b, t, 0, 1);
}
+ // Apply custom rotation to the projection.
+ float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
+ switch (rotation) {
+ case Transform::ROT_0:
+ break;
+ case Transform::ROT_90:
+ m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
+ break;
+ case Transform::ROT_180:
+ m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
+ break;
+ case Transform::ROT_270:
+ m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
+ break;
+ default:
+ break;
+ }
+
glViewport(0, 0, vpw, vph);
mState.setProjectionMatrix(m);
mVpWidth = vpw;
#include <sys/types.h>
#include <GLES2/gl2.h>
+#include <Transform.h>
#include "RenderEngine.h"
#include "ProgramCache.h"
virtual void dump(String8& result);
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap);
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation);
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha);
virtual void setupDimLayerBlending(int alpha);
virtual void setupLayerTexturing(const Texture& texture);
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <ui/mat4.h>
+#include <Transform.h>
#define EGL_NO_CONFIG ((EGLConfig)0)
// set-up
virtual void checkErrors() const;
virtual void setViewportAndProjection(size_t vpw, size_t vph,
- Rect sourceCrop, size_t hwh, bool yswap) = 0;
+ Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0;
virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
virtual void setupDimLayerBlending(int alpha) = 0;
virtual void setupLayerTexturing(const Texture& texture) = 0;
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) {
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
}
}
+ // Convert to surfaceflinger's internal rotation type.
+ Transform::orientation_flags rotationFlags;
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ rotationFlags = Transform::ROT_0;
+ break;
+ case ISurfaceComposer::eRotate90:
+ rotationFlags = Transform::ROT_90;
+ break;
+ case ISurfaceComposer::eRotate180:
+ rotationFlags = Transform::ROT_180;
+ break;
+ case ISurfaceComposer::eRotate270:
+ rotationFlags = Transform::ROT_270;
+ break;
+ default:
+ rotationFlags = Transform::ROT_0;
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ break;
+ }
+
class MessageCaptureScreen : public MessageBase {
SurfaceFlinger* flinger;
sp<IBinder> display;
uint32_t reqWidth, reqHeight;
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
+ Transform::orientation_flags rotation;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
+ rotation(rotation),
result(PERMISSION_DENIED)
{
}
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotation);
static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
return true;
}
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotationFlags);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
const sp<const DisplayDevice>& hw,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool yswap, bool useIdentityTransform)
+ bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
RenderEngine& engine(getRenderEngine());
engine.checkErrors();
// set-up our viewport
- engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap);
+ engine.setViewportAndProjection(
+ reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
engine.disableTexturing();
// redraw the screen entirely...
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
// via an FBO, which means we didn't have to create
// an EGLSurface and therefore we're not
// dependent on the context's EGLConfig.
- renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight,
- minLayerZ, maxLayerZ, true, useIdentityTransform);
+ renderScreenImplLocked(
+ hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
+ useIdentityTransform, rotation);
// Attempt to create a sync khr object that can produce a sync point. If that
// isn't available, create a non-dupable sync object in the fallback path and
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform);
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& display);
const sp<const DisplayDevice>& hw,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool yswap, bool useIdentityTransform);
+ bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation);
status_t captureScreenImplLocked(
const sp<const DisplayDevice>& hw,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform);
+ bool useIdentityTransform, Transform::orientation_flags rotation);
/* ------------------------------------------------------------------------
* EGL