blob: 786b927d35eb78de7e7cd246daa6f83129465cc9 [file] [log] [blame]
Romain Guye4d01122010-06-16 18:44:05 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Romain Guy85bf02f2010-06-22 13:11:24 -070017#define LOG_TAG "OpenGLRenderer"
Romain Guye4d01122010-06-16 18:44:05 -070018
19#include <stdlib.h>
20#include <stdint.h>
21#include <sys/types.h>
22
23#include <utils/Errors.h>
Romain Guy9d5316e2010-06-24 19:30:36 -070024#include <utils/KeyedVector.h>
Romain Guye4d01122010-06-16 18:44:05 -070025#include <utils/Log.h>
26
27#include <GLES2/gl2.h>
28#include <GLES2/gl2ext.h>
29
Romain Guybd6b79b2010-06-26 00:13:53 -070030#include <SkCanvas.h>
Romain Guyc7d53492010-06-25 13:41:57 -070031#include <SkPaint.h>
Romain Guy85bf02f2010-06-22 13:11:24 -070032#include <SkXfermode.h>
33
34#include "OpenGLRenderer.h"
35#include "Matrix.h"
Romain Guye4d01122010-06-16 18:44:05 -070036
37namespace android {
Romain Guy9d5316e2010-06-24 19:30:36 -070038namespace uirenderer {
39
40///////////////////////////////////////////////////////////////////////////////
41// Defines
42///////////////////////////////////////////////////////////////////////////////
43
Romain Guybd6b79b2010-06-26 00:13:53 -070044#define SV(x, y) { { x, y } }
45#define FV(x, y, u, v) { { x, y }, { u, v } }
Romain Guy9d5316e2010-06-24 19:30:36 -070046
47///////////////////////////////////////////////////////////////////////////////
48// Globals
49///////////////////////////////////////////////////////////////////////////////
50
Romain Guyc7d53492010-06-25 13:41:57 -070051const SimpleVertex gDrawColorVertices[] = {
Romain Guybd6b79b2010-06-26 00:13:53 -070052 SV(0.0f, 0.0f),
53 SV(1.0f, 0.0f),
54 SV(0.0f, 1.0f),
55 SV(1.0f, 1.0f)
Romain Guy9d5316e2010-06-24 19:30:36 -070056};
Romain Guyc7d53492010-06-25 13:41:57 -070057const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex);
58const GLsizei gDrawColorVertexCount = 4;
Romain Guy9d5316e2010-06-24 19:30:36 -070059
Romain Guybd6b79b2010-06-26 00:13:53 -070060const TextureVertex gDrawTextureVertices[] = {
61 FV(0.0f, 0.0f, 0.0f, 1.0f),
62 FV(1.0f, 0.0f, 1.0f, 1.0f),
63 FV(0.0f, 1.0f, 0.0f, 0.0f),
64 FV(1.0f, 1.0f, 1.0f, 0.0f)
65};
66const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex);
67const GLsizei gDrawTextureVertexCount = 4;
68
Romain Guy9d5316e2010-06-24 19:30:36 -070069///////////////////////////////////////////////////////////////////////////////
70// Shaders
71///////////////////////////////////////////////////////////////////////////////
72
73#define SHADER_SOURCE(name, source) const char* name = #source
74
75#include "shaders/drawColor.vert"
76#include "shaders/drawColor.frag"
77
Romain Guybd6b79b2010-06-26 00:13:53 -070078#include "shaders/drawTexture.vert"
79#include "shaders/drawTexture.frag"
80
Romain Guy9d5316e2010-06-24 19:30:36 -070081Program::Program(const char* vertex, const char* fragment) {
Romain Guy7ae7ac42010-06-25 13:46:18 -070082 vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
83 fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
Romain Guy9d5316e2010-06-24 19:30:36 -070084
Romain Guy7ae7ac42010-06-25 13:46:18 -070085 id = glCreateProgram();
86 glAttachShader(id, vertexShader);
87 glAttachShader(id, fragmentShader);
88 glLinkProgram(id);
Romain Guy9d5316e2010-06-24 19:30:36 -070089
Romain Guy7ae7ac42010-06-25 13:46:18 -070090 GLint status;
91 glGetProgramiv(id, GL_LINK_STATUS, &status);
92 if (status != GL_TRUE) {
93 GLint infoLen = 0;
94 glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
95 if (infoLen > 1) {
96 char* log = (char*) malloc(sizeof(char) * infoLen);
97 glGetProgramInfoLog(id, infoLen, 0, log);
98 LOGE("Error while linking shaders: %s", log);
99 delete log;
100 }
101 glDeleteProgram(id);
102 }
Romain Guy9d5316e2010-06-24 19:30:36 -0700103}
104
105Program::~Program() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700106 glDeleteShader(vertexShader);
107 glDeleteShader(fragmentShader);
108 glDeleteProgram(id);
Romain Guy9d5316e2010-06-24 19:30:36 -0700109}
110
111void Program::use() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700112 glUseProgram(id);
Romain Guy9d5316e2010-06-24 19:30:36 -0700113}
114
115int Program::addAttrib(const char* name) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700116 int slot = glGetAttribLocation(id, name);
117 attributes.add(name, slot);
118 return slot;
Romain Guy9d5316e2010-06-24 19:30:36 -0700119}
120
121int Program::getAttrib(const char* name) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700122 return attributes.valueFor(name);
Romain Guy9d5316e2010-06-24 19:30:36 -0700123}
124
125int Program::addUniform(const char* name) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700126 int slot = glGetUniformLocation(id, name);
127 uniforms.add(name, slot);
128 return slot;
Romain Guy9d5316e2010-06-24 19:30:36 -0700129}
130
131int Program::getUniform(const char* name) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700132 return uniforms.valueFor(name);
Romain Guy9d5316e2010-06-24 19:30:36 -0700133}
134
135GLuint Program::buildShader(const char* source, GLenum type) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700136 GLuint shader = glCreateShader(type);
137 glShaderSource(shader, 1, &source, 0);
138 glCompileShader(shader);
Romain Guy9d5316e2010-06-24 19:30:36 -0700139
Romain Guy7ae7ac42010-06-25 13:46:18 -0700140 GLint status;
141 glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
142 if (status != GL_TRUE) {
143 // Some drivers return wrong values for GL_INFO_LOG_LENGTH
144 // use a fixed size instead
145 GLchar log[512];
146 glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
147 LOGE("Error while compiling shader: %s", log);
148 glDeleteShader(shader);
149 }
Romain Guy9d5316e2010-06-24 19:30:36 -0700150
Romain Guy7ae7ac42010-06-25 13:46:18 -0700151 return shader;
Romain Guy9d5316e2010-06-24 19:30:36 -0700152}
153
154DrawColorProgram::DrawColorProgram():
Romain Guy7ae7ac42010-06-25 13:46:18 -0700155 Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
Romain Guybd6b79b2010-06-26 00:13:53 -0700156 getAttribsAndUniforms();
157}
158
159DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
160 Program(vertex, fragment) {
161 getAttribsAndUniforms();
162}
163
164void DrawColorProgram::getAttribsAndUniforms() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700165 position = addAttrib("position");
166 color = addAttrib("color");
167 projection = addUniform("projection");
168 modelView = addUniform("modelView");
169 transform = addUniform("transform");
Romain Guyc7d53492010-06-25 13:41:57 -0700170}
171
172void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
173 const GLfloat* transformMatrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700174 Program::use();
175 glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix);
176 glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix);
177 glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix);
Romain Guy9d5316e2010-06-24 19:30:36 -0700178}
179
Romain Guybd6b79b2010-06-26 00:13:53 -0700180DrawTextureProgram::DrawTextureProgram():
181 DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
182 texCoords = addAttrib("texCoords");
183 sampler = addUniform("sampler");
184}
185
Romain Guy9d5316e2010-06-24 19:30:36 -0700186///////////////////////////////////////////////////////////////////////////////
187// Support
188///////////////////////////////////////////////////////////////////////////////
189
190const Rect& Snapshot::getMappedClip() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700191 if (flags & kFlagDirtyTransform) {
192 flags &= ~kFlagDirtyTransform;
193 mappedClip.set(clipRect);
194 transform.mapRect(mappedClip);
195 }
196 return mappedClip;
Romain Guy9d5316e2010-06-24 19:30:36 -0700197}
Romain Guye4d01122010-06-16 18:44:05 -0700198
Romain Guyf6a11b82010-06-23 17:47:49 -0700199///////////////////////////////////////////////////////////////////////////////
200// Constructors/destructor
201///////////////////////////////////////////////////////////////////////////////
202
Romain Guy85bf02f2010-06-22 13:11:24 -0700203OpenGLRenderer::OpenGLRenderer() {
204 LOGD("Create OpenGLRenderer");
Romain Guy9d5316e2010-06-24 19:30:36 -0700205
206 mDrawColorShader = new DrawColorProgram;
Romain Guybd6b79b2010-06-26 00:13:53 -0700207 mDrawTextureShader = new DrawTextureProgram;
Romain Guye4d01122010-06-16 18:44:05 -0700208}
209
Romain Guy85bf02f2010-06-22 13:11:24 -0700210OpenGLRenderer::~OpenGLRenderer() {
211 LOGD("Destroy OpenGLRenderer");
Romain Guye4d01122010-06-16 18:44:05 -0700212}
213
Romain Guyf6a11b82010-06-23 17:47:49 -0700214///////////////////////////////////////////////////////////////////////////////
215// Setup
216///////////////////////////////////////////////////////////////////////////////
217
Romain Guy85bf02f2010-06-22 13:11:24 -0700218void OpenGLRenderer::setViewport(int width, int height) {
Romain Guy08ae3172010-06-21 19:35:50 -0700219 glViewport(0, 0, width, height);
220
221 mat4 ortho;
Romain Guyc7d53492010-06-25 13:41:57 -0700222 ortho.loadOrtho(0, width, height, 0, -1, 1);
Romain Guy08ae3172010-06-21 19:35:50 -0700223 ortho.copyTo(mOrthoMatrix);
Romain Guybb9524b2010-06-22 18:56:38 -0700224
225 mWidth = width;
226 mHeight = height;
Romain Guye4d01122010-06-16 18:44:05 -0700227}
228
Romain Guy85bf02f2010-06-22 13:11:24 -0700229void OpenGLRenderer::prepare() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700230 mSnapshot = &mFirstSnapshot;
231 mSaveCount = 0;
Romain Guyf6a11b82010-06-23 17:47:49 -0700232
Romain Guy08ae3172010-06-21 19:35:50 -0700233 glDisable(GL_SCISSOR_TEST);
Romain Guybb9524b2010-06-22 18:56:38 -0700234
Romain Guy08ae3172010-06-21 19:35:50 -0700235 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
236 glClear(GL_COLOR_BUFFER_BIT);
Romain Guybb9524b2010-06-22 18:56:38 -0700237
Romain Guy08ae3172010-06-21 19:35:50 -0700238 glEnable(GL_SCISSOR_TEST);
Romain Guyc7d53492010-06-25 13:41:57 -0700239 glScissor(0, 0, mWidth, mHeight);
Romain Guyf6a11b82010-06-23 17:47:49 -0700240
Romain Guybb9524b2010-06-22 18:56:38 -0700241 mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight);
242}
243
Romain Guyf6a11b82010-06-23 17:47:49 -0700244///////////////////////////////////////////////////////////////////////////////
245// State management
246///////////////////////////////////////////////////////////////////////////////
247
Romain Guybb9524b2010-06-22 18:56:38 -0700248int OpenGLRenderer::getSaveCount() const {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700249 return mSaveCount;
Romain Guybb9524b2010-06-22 18:56:38 -0700250}
251
252int OpenGLRenderer::save(int flags) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700253 return saveSnapshot();
Romain Guybb9524b2010-06-22 18:56:38 -0700254}
255
256void OpenGLRenderer::restore() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700257 if (mSaveCount == 0) return;
Romain Guybb9524b2010-06-22 18:56:38 -0700258
Romain Guy7ae7ac42010-06-25 13:46:18 -0700259 if (restoreSnapshot()) {
260 setScissorFromClip();
261 }
Romain Guybb9524b2010-06-22 18:56:38 -0700262}
263
264void OpenGLRenderer::restoreToCount(int saveCount) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700265 if (saveCount <= 0 || saveCount > mSaveCount) return;
Romain Guybb9524b2010-06-22 18:56:38 -0700266
Romain Guy7ae7ac42010-06-25 13:46:18 -0700267 bool restoreClip = false;
Romain Guybb9524b2010-06-22 18:56:38 -0700268
Romain Guy7ae7ac42010-06-25 13:46:18 -0700269 while (mSaveCount != saveCount - 1) {
270 restoreClip |= restoreSnapshot();
271 }
Romain Guybb9524b2010-06-22 18:56:38 -0700272
Romain Guy7ae7ac42010-06-25 13:46:18 -0700273 if (restoreClip) {
274 setScissorFromClip();
275 }
Romain Guybb9524b2010-06-22 18:56:38 -0700276}
277
278int OpenGLRenderer::saveSnapshot() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700279 mSnapshot = new Snapshot(mSnapshot);
280 return ++mSaveCount;
Romain Guybb9524b2010-06-22 18:56:38 -0700281}
282
283bool OpenGLRenderer::restoreSnapshot() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700284 bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
Romain Guybd6b79b2010-06-26 00:13:53 -0700285 bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer;
Romain Guybb9524b2010-06-22 18:56:38 -0700286
Romain Guybd6b79b2010-06-26 00:13:53 -0700287 sp<Snapshot> current = mSnapshot;
288 sp<Snapshot> previous = mSnapshot->previous;
289
290 if (restoreLayer) {
291 // Unbind current FBO and restore previous one
292 // Most of the time, previous->fbo will be 0 to bind the default buffer
293 glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
294
295 const Rect& layer = current->layer;
296 clipRect(layer.left, layer.top, layer.right, layer.bottom);
297 mSnapshot->transform.loadIdentity();
298
299 drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha);
300
301 glDeleteFramebuffers(1, &current->fbo);
302 glDeleteTextures(1, &current->texture);
303 }
304
305 mSnapshot = previous;
Romain Guy7ae7ac42010-06-25 13:46:18 -0700306 mSaveCount--;
Romain Guyf6a11b82010-06-23 17:47:49 -0700307
Romain Guy7ae7ac42010-06-25 13:46:18 -0700308 return restoreClip;
Romain Guybb9524b2010-06-22 18:56:38 -0700309}
310
Romain Guyf6a11b82010-06-23 17:47:49 -0700311///////////////////////////////////////////////////////////////////////////////
Romain Guybd6b79b2010-06-26 00:13:53 -0700312// Layers
313///////////////////////////////////////////////////////////////////////////////
314
315int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
316 const SkPaint* p, int flags) {
317 // TODO Implement
318 return saveSnapshot();
319}
320
321int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
322 int alpha, int flags) {
323 int count = saveSnapshot();
324
325 mSnapshot->flags |= Snapshot::kFlagIsLayer;
326 mSnapshot->alpha = alpha / 255.0f;
327 mSnapshot->layer.set(left, top, right, bottom);
328
329 // Generate the FBO and attach the texture
330 glGenFramebuffers(1, &mSnapshot->fbo);
331 glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo);
332
333 // Generate the texture in which the FBO will draw
334 glGenTextures(1, &mSnapshot->texture);
335 glBindTexture(GL_TEXTURE_2D, mSnapshot->texture);
336
337 // The FBO will not be scaled, so we can use lower quality filtering
338 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
340
341 // TODO ***** IMPORTANT *****
342 // Creating a texture-backed FBO works only if the texture is the same size
343 // as the original rendering buffer (in this case, mWidth and mHeight.)
344 // This is expensive and wasteful and must be fixed.
345
346 const GLsizei width = mWidth; //right - left;
347 const GLsizei height = mHeight; //bottom - right;
348
349 const GLint format = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) ? GL_RGBA : GL_RGB;
350 glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
351 glBindTexture(GL_TEXTURE_2D, 0);
352
353 // Bind texture to FBO
354 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
355 mSnapshot->texture, 0);
356
357 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
358 if (status != GL_FRAMEBUFFER_COMPLETE) {
359 LOGD("Framebuffer incomplete %d", status);
360
361 glDeleteFramebuffers(1, &mSnapshot->fbo);
362 glDeleteTextures(1, &mSnapshot->texture);
363 }
364
365 return count;
366}
367
368///////////////////////////////////////////////////////////////////////////////
Romain Guyf6a11b82010-06-23 17:47:49 -0700369// Transforms
370///////////////////////////////////////////////////////////////////////////////
371
372void OpenGLRenderer::translate(float dx, float dy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700373 mSnapshot->transform.translate(dx, dy, 0.0f);
374 mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
Romain Guyf6a11b82010-06-23 17:47:49 -0700375}
376
377void OpenGLRenderer::rotate(float degrees) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700378 mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f);
379 mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
Romain Guyf6a11b82010-06-23 17:47:49 -0700380}
381
382void OpenGLRenderer::scale(float sx, float sy) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700383 mSnapshot->transform.scale(sx, sy, 1.0f);
384 mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
Romain Guyf6a11b82010-06-23 17:47:49 -0700385}
386
387void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700388 mSnapshot->transform.load(*matrix);
389 mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
Romain Guyf6a11b82010-06-23 17:47:49 -0700390}
391
392void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700393 mSnapshot->transform.copyTo(*matrix);
Romain Guyf6a11b82010-06-23 17:47:49 -0700394}
395
396void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700397 mat4 m(*matrix);
398 mSnapshot->transform.multiply(m);
399 mSnapshot->flags |= Snapshot::kFlagDirtyTransform;
Romain Guyf6a11b82010-06-23 17:47:49 -0700400}
401
402///////////////////////////////////////////////////////////////////////////////
403// Clipping
404///////////////////////////////////////////////////////////////////////////////
405
Romain Guybb9524b2010-06-22 18:56:38 -0700406void OpenGLRenderer::setScissorFromClip() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700407 const Rect& clip = mSnapshot->getMappedClip();
408 glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
Romain Guy9d5316e2010-06-24 19:30:36 -0700409}
410
411const Rect& OpenGLRenderer::getClipBounds() {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700412 return mSnapshot->clipRect;
Romain Guybb9524b2010-06-22 18:56:38 -0700413}
414
Romain Guyc7d53492010-06-25 13:41:57 -0700415bool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) {
416 /*
417 * The documentation of quickReject() indicates that the specified rect
418 * is transformed before being compared to the clip rect. However, the
419 * clip rect is not stored transformed in the snapshot and can thus be
420 * compared directly
421 *
422 * The following code can be used instead to performed a mapped comparison:
423 *
424 * mSnapshot->transform.mapRect(r);
425 * const Rect& clip = mSnapshot->getMappedClip();
426 * return !clip.intersects(r);
427 */
428
429 Rect r(left, top, right, bottom);
430 return !mSnapshot->clipRect.intersects(r);
431}
432
Romain Guybb9524b2010-06-22 18:56:38 -0700433bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
Romain Guy7ae7ac42010-06-25 13:46:18 -0700434 bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
435 if (clipped) {
436 mSnapshot->flags |= Snapshot::kFlagClipSet;
437 setScissorFromClip();
438 }
439 return clipped;
Romain Guye4d01122010-06-16 18:44:05 -0700440}
441
Romain Guyf6a11b82010-06-23 17:47:49 -0700442///////////////////////////////////////////////////////////////////////////////
443// Drawing
444///////////////////////////////////////////////////////////////////////////////
445
Romain Guy85bf02f2010-06-22 13:11:24 -0700446void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
Romain Guyc7d53492010-06-25 13:41:57 -0700447 // TODO: Set the transfer mode
448 const Rect& clip = mSnapshot->clipRect;
449 drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color);
450}
Romain Guy9d5316e2010-06-24 19:30:36 -0700451
Romain Guybd6b79b2010-06-26 00:13:53 -0700452void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) {
Romain Guyc7d53492010-06-25 13:41:57 -0700453 // TODO Support more than just color
454 // TODO: Set the transfer mode
Romain Guybd6b79b2010-06-26 00:13:53 -0700455 drawColorRect(left, top, right, bottom, p->getColor());
Romain Guyc7d53492010-06-25 13:41:57 -0700456}
Romain Guy9d5316e2010-06-24 19:30:36 -0700457
Romain Guyc7d53492010-06-25 13:41:57 -0700458void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) {
459 GLfloat a = ((color >> 24) & 0xFF) / 255.0f;
460 GLfloat r = ((color >> 16) & 0xFF) / 255.0f;
461 GLfloat g = ((color >> 8) & 0xFF) / 255.0f;
462 GLfloat b = ((color ) & 0xFF) / 255.0f;
Romain Guy9d5316e2010-06-24 19:30:36 -0700463
Romain Guyc7d53492010-06-25 13:41:57 -0700464 mModelView.loadTranslate(left, top, 0.0f);
465 mModelView.scale(right - left, bottom - top, 1.0f);
Romain Guy9d5316e2010-06-24 19:30:36 -0700466
Romain Guyc7d53492010-06-25 13:41:57 -0700467 mDrawColorShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);
Romain Guy9d5316e2010-06-24 19:30:36 -0700468
Romain Guyc7d53492010-06-25 13:41:57 -0700469 const GLvoid* p = &gDrawColorVertices[0].position[0];
Romain Guy9d5316e2010-06-24 19:30:36 -0700470
Romain Guyc7d53492010-06-25 13:41:57 -0700471 glEnableVertexAttribArray(mDrawColorShader->position);
472 glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE,
473 gDrawColorVertexStride, p);
474 glVertexAttrib4f(mDrawColorShader->color, r, g, b, a);
Romain Guy9d5316e2010-06-24 19:30:36 -0700475
Romain Guyc7d53492010-06-25 13:41:57 -0700476 glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount);
Romain Guy9d5316e2010-06-24 19:30:36 -0700477
Romain Guyc7d53492010-06-25 13:41:57 -0700478 glDisableVertexAttribArray(mDrawColorShader->position);
Romain Guy85bf02f2010-06-22 13:11:24 -0700479}
480
Romain Guybd6b79b2010-06-26 00:13:53 -0700481void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
482 GLuint texture, float alpha) {
483 mModelView.loadTranslate(left, top, 0.0f);
484 mModelView.scale(right - left, bottom - top, 1.0f);
485
486 mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);
487
488 // TODO Correctly set the blend function
489 glEnable(GL_BLEND);
490 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
491
492 glBindTexture(GL_TEXTURE_2D, texture);
493
494 glActiveTexture(GL_TEXTURE0);
495 glUniform1i(mDrawTextureShader->sampler, 0);
496
497 const GLvoid* p = &gDrawTextureVertices[0].position[0];
498 const GLvoid* t = &gDrawTextureVertices[0].texture[0];
499
500 glEnableVertexAttribArray(mDrawTextureShader->position);
501 glVertexAttribPointer(mDrawTextureShader->position, 2, GL_FLOAT, GL_FALSE,
502 gDrawTextureVertexStride, p);
503
504 glEnableVertexAttribArray(mDrawTextureShader->texCoords);
505 glVertexAttribPointer(mDrawTextureShader->texCoords, 2, GL_FLOAT, GL_FALSE,
506 gDrawTextureVertexStride, t);
507
508 glVertexAttrib4f(mDrawTextureShader->color, 1.0f, 1.0f, 1.0f, alpha);
509
510 glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount);
511
512 glDisableVertexAttribArray(mDrawTextureShader->position);
513 glDisableVertexAttribArray(mDrawTextureShader->texCoords);
514
515 glBindTexture(GL_TEXTURE_2D, 0);
516 glDisable(GL_BLEND);
517}
518
Romain Guy9d5316e2010-06-24 19:30:36 -0700519}; // namespace uirenderer
Romain Guye4d01122010-06-16 18:44:05 -0700520}; // namespace android