1/*
2 * Copyright (C) 2011 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
17#include <GLES/gl.h>
18#include <GLES2/gl2.h>
19#include <GLES/glext.h>
20
21#include <rs_hal.h>
22#include <rsContext.h>
23#include <rsPath.h>
24
25#include "rsdCore.h"
26#include "rsdPath.h"
27#include "rsdAllocation.h"
28#include "rsdGL.h"
29#include "rsdVertexArray.h"
30#include "rsdShaderCache.h"
31
32using namespace android;
33using namespace android::renderscript;
34
35class DrvPath {
36protected:
37    DrvPath();
38public:
39    virtual ~DrvPath();
40    virtual void draw(Context *) = 0;
41};
42
43class DrvPathStatic : public DrvPath {
44public:
45    typedef struct {
46        float x1, xc, x2;
47        float y1, yc, y2;
48    } segment_t;
49
50    segment_t *mSegments;
51    uint32_t mSegmentCount;
52
53    DrvPathStatic(const Allocation *vtx, const Allocation *loops);
54    virtual ~DrvPathStatic();
55
56    virtual void draw(Context *);
57};
58
59class DrvPathDynamic : public DrvPath {
60public:
61    DrvPathDynamic();
62    virtual ~DrvPathDynamic();
63};
64
65static void cleanup(const Context *rsc, const Path *m) {
66    DrvPath *dp = (DrvPath *)m->mHal.drv;
67    if (dp) {
68        delete dp;
69    }
70}
71
72bool rsdPathInitStatic(const Context *rsc, const Path *m,
73                       const Allocation *vtx, const Allocation *loops) {
74    DrvPathStatic *drv = NULL;
75    cleanup(rsc, m);
76
77    DrvPathStatic *dps = new DrvPathStatic(vtx, loops);
78    //LOGE("init path m %p,  %p", m, dps);
79    m->mHal.drv = dps;
80    return dps != NULL;
81}
82
83bool rsdPathInitDynamic(const Context *rsc, const Path *m) {
84    return false;
85}
86
87
88void rsdPathDraw(const Context *rsc, const Path *m) {
89    //LOGE("render m=%p", m);
90
91    DrvPath *drv = (DrvPath *)m->mHal.drv;
92    if(drv) {
93        //LOGE("render 2 drv=%p", drv);
94        drv->draw((Context *)rsc);
95    }
96}
97
98void rsdPathDestroy(const Context *rsc, const Path *m) {
99    cleanup(rsc, m);
100    m->mHal.drv = NULL;
101}
102
103
104
105
106DrvPath::DrvPath() {
107}
108
109DrvPath::~DrvPath() {
110}
111
112DrvPathStatic::DrvPathStatic(const Allocation *vtx, const Allocation *loops) {
113    mSegmentCount = vtx->getType()->getDimX() / 3;
114    mSegments = new segment_t[mSegmentCount];
115/*
116    const float *fin = (const float *)vtx->getPtr();
117    for (uint32_t ct=0; ct < mSegmentCount; ct++) {
118        segment_t *s = &mSegments[ct];
119        s->x1 = fin[0];
120        s->y1 = fin[1];
121
122        s->xc = fin[2];
123        s->yc = fin[3];
124
125        s->x2 = fin[4];
126        s->y2 = fin[5];
127        fin += 6;
128    }
129    */
130}
131
132DrvPathStatic::~DrvPathStatic() {
133}
134
135void DrvPathStatic::draw(Context *rsc) {
136    const static float color[24] = {
137        1.f, 0.f, 0.f, 1.f,  0.5f, 0.f, 0.f, 1.f,
138        1.f, 0.f, 0.f, 1.f,  0.5f, 0.f, 0.f, 1.f,
139        1.f, 1.f, 1.f, 1.f,  1.f, 1.f, 1.f, 1.f};
140    float vtx[12];
141
142    //LOGE("draw");
143    if (!rsc->setupCheck()) {
144        return;
145    }
146
147    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
148    if (!dc->gl.shaderCache->setup(rsc)) {
149        return;
150    }
151
152    RsdVertexArray::Attrib attribs[2];
153    attribs[0].set(GL_FLOAT, 2, 8, false, (size_t)vtx, "ATTRIB_position");
154    attribs[1].set(GL_FLOAT, 4, 16, false, (size_t)color, "ATTRIB_color");
155    RsdVertexArray va(attribs, 2);
156    va.setup(rsc);
157
158    //LOGE("mSegmentCount %i", mSegmentCount);
159    for (uint32_t ct=0; ct < mSegmentCount; ct++) {
160        segment_t *s = &mSegments[ct];
161
162        vtx[0] = s->x1;
163        vtx[1] = s->y1;
164        vtx[2] = s->xc;
165        vtx[3] = s->yc;
166
167        vtx[4] = s->x2;
168        vtx[5] = s->y2;
169        vtx[6] = s->xc;
170        vtx[7] = s->yc;
171
172        vtx[8] = s->x1;
173        vtx[9] = s->y1;
174        vtx[10] = s->x2;
175        vtx[11] = s->y2;
176
177        RSD_CALL_GL(glDrawArrays, GL_LINES, 0, 6);
178    }
179
180}
181
182DrvPathDynamic::DrvPathDynamic() {
183}
184
185DrvPathDynamic::~DrvPathDynamic() {
186}
187