summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-09-19 17:25:38 -0700
committerRomain Guy <romainguy@google.com>2012-09-19 21:10:09 -0700
commit2b7028eabac80cec170572bc0e945a1d4224e595 (patch)
tree116f24c751ece653a5c1e08aa9c142ad1e142b25 /libs
parent4be07ade3658da9345067780520ddbd266900ee4 (diff)
downloadframeworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.zip
frameworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.tar.gz
frameworks_base-2b7028eabac80cec170572bc0e945a1d4224e595.tar.bz2
Add support for QCOM_tiled_rendering
Bug #7186819 This optional OpenGL extension can be used by tiled renderers to optimize copies from main memory to tiles memory. Change-Id: Id4a5d64e61ad17f50e773e8104b9bf584bb65077
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/Caches.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp50
-rw-r--r--libs/hwui/OpenGLRenderer.h18
3 files changed, 56 insertions, 16 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index edb4c10..b149bb9 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -429,13 +429,13 @@ void Caches::resetScissor() {
void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) {
if (extensions.hasTiledRendering()) {
-
+ glStartTilingQCOM(x, y, width, height, GL_COLOR_BUFFER_BIT0_QCOM);
}
}
void Caches::endTiling() {
if (extensions.hasTiledRendering()) {
-
+ glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
}
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 11eb7a1..9b9ca12 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -175,7 +175,7 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
mSaveCount = 1;
mSnapshot->setClip(left, top, right, bottom);
- mDirtyClip = opaque;
+ mDirtyClip = mOpaqueFrame = opaque;
// If we know that we are going to redraw the entire framebuffer,
// perform a discard to let the driver know we don't need to preserve
@@ -188,6 +188,9 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
syncState();
+ mTilingSnapshot = mSnapshot;
+ startTiling();
+
if (!opaque) {
mCaches.enableScissor();
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
@@ -210,7 +213,30 @@ void OpenGLRenderer::syncState() {
}
}
+void OpenGLRenderer::startTiling() {
+ startTiling(mTilingSnapshot);
+}
+
+void OpenGLRenderer::startTiling(const sp<Snapshot>& s) {
+ bool opaque = mOpaqueFrame;
+ Rect* clip = mTilingSnapshot->clipRect;
+
+ if (s->flags & Snapshot::kFlagIsFboLayer) {
+ opaque = !s->layer->isBlend();
+ clip = s->clipRect;
+ }
+
+ mCaches.startTiling(clip->left, s->height - clip->bottom,
+ clip->right - clip->left, clip->bottom - clip->top, opaque);
+}
+
+void OpenGLRenderer::endTiling() {
+ mCaches.endTiling();
+}
+
void OpenGLRenderer::finish() {
+ endTiling();
+
#if DEBUG_OPENGL
GLenum status = GL_NO_ERROR;
while ((status = glGetError()) != GL_NO_ERROR) {
@@ -637,6 +663,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui
mSnapshot->flags |= Snapshot::kFlagDirtyOrtho;
mSnapshot->orthoMatrix.load(mOrthoMatrix);
+ endTiling();
// Bind texture to FBO
glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo());
layer->bindTexture();
@@ -650,18 +677,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
layer->getTexture(), 0);
-#if DEBUG_LAYERS_AS_REGIONS
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- ALOGE("Framebuffer incomplete (GL error code 0x%x)", status);
-
- glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
-
- Caches::getInstance().resourceCache.decrementRefcount(layer);
-
- return false;
- }
-#endif
+ startTiling(mSnapshot);
// Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
mCaches.enableScissor();
@@ -690,11 +706,14 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
if (fboLayer) {
+ endTiling();
+
// Detach the texture from the FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
-
// Unbind current FBO and restore previous one
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
+
+ startTiling(previous);
}
Layer* layer = current->layer;
@@ -2621,12 +2640,15 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* pain
OpenGLRenderer* renderer = layer->renderer;
Rect& dirty = layer->dirtyRect;
+ endTiling();
+
renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend());
renderer->drawDisplayList(layer->displayList, dirty, DisplayList::kReplayFlag_ClipChildren);
renderer->finish();
resumeAfterLayer();
+ startTiling(mSnapshot);
dirty.setEmpty();
layer->deferredUpdateScheduled = false;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 8dcd33f..10ba86e 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -347,6 +347,20 @@ private:
void syncState();
/**
+ * Tells the GPU what part of the screen is about to be redrawn.
+ * This method needs to be invoked every time getTargetFbo() is
+ * bound again.
+ */
+ void startTiling();
+ void startTiling(const sp<Snapshot>& snapshot);
+
+ /**
+ * Tells the GPU that we are done drawing the frame or that we
+ * are switching to another render target.
+ */
+ void endTiling();
+
+ /**
* Saves the current state of the renderer as a new snapshot.
* The new snapshot is saved in mSnapshot and the previous snapshot
* is linked from mSnapshot->previous.
@@ -735,6 +749,8 @@ private:
sp<Snapshot> mFirstSnapshot;
// Current state
sp<Snapshot> mSnapshot;
+ // State used to define the clipping region
+ sp<Snapshot> mTilingSnapshot;
// Shaders
SkiaShader* mShader;
@@ -784,6 +800,8 @@ private:
GLuint mTextureUnit;
// Track dirty regions, true by default
bool mTrackDirtyRegions;
+ // Indicate whether we are drawing an opaque frame
+ bool mOpaqueFrame;
friend class DisplayListRenderer;