diff options
Diffstat (limited to 'libs/rs')
31 files changed, 158 insertions, 700 deletions
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 2f60c9f..1e24cd2 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -49,7 +49,7 @@ typedef void * RsProgramFragmentStore; RsDevice rsDeviceCreate(); void rsDeviceDestroy(RsDevice); -RsContext rsContextCreate(RsDevice, void *, uint32_t version); +RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth); void rsContextDestroy(RsContext); void rsObjDestroyOOB(RsContext, void *); diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java index fa2caa7..7468d2b 100644 --- a/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java +++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallView.java @@ -36,7 +36,7 @@ class FallView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); - RenderScript RS = createRenderScript(); + RenderScript RS = createRenderScript(false); mRender = new FallRS(w, h); mRender.init(RS, getResources()); } diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java index 73b7414..1c5b2bc 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmView.java +++ b/libs/rs/java/Film/src/com/android/film/FilmView.java @@ -52,7 +52,7 @@ public class FilmView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); - mRS = createRenderScript(); + mRS = createRenderScript(true); mRender = new FilmRS(); mRender.init(mRS, getResources(), w, h); } diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c index e7804a5..8c1cad4 100644 --- a/libs/rs/java/Fountain/res/raw/fountain.c +++ b/libs/rs/java/Fountain/res/raw/fountain.c @@ -12,7 +12,6 @@ int main(int launchID) { float height = getHeight(); if (rate) { - debugI32("rate", rate); int *dataI = loadArrayI32(1, 0); float rMax = ((float)rate) * 0.005f; int x = Control_x; diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java index 2768e2c..7826161 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java @@ -52,7 +52,7 @@ public class FountainView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); - mRS = createRenderScript(); + mRS = createRenderScript(false); mRender = new FountainRS(); mRender.init(mRS, getResources(), w, h); } diff --git a/libs/rs/java/Galaxy/Android.mk b/libs/rs/java/Galaxy/Android.mk deleted file mode 100644 index 0884e18..0000000 --- a/libs/rs/java/Galaxy/Android.mk +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (C) 2009 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. -# - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript - -LOCAL_PACKAGE_NAME := GalaxyRS - -include $(BUILD_PACKAGE) diff --git a/libs/rs/java/Galaxy/AndroidManifest.xml b/libs/rs/java/Galaxy/AndroidManifest.xml deleted file mode 100644 index 6da1e0f..0000000 --- a/libs/rs/java/Galaxy/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.galaxy.rs"> - - <application android:label="GalaxyRS"> - - <activity - android:screenOrientation="portrait" - android:name="Galaxy" - android:theme="@android:style/Theme.NoTitleBar"> - - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - - </activity> - - </application> - -</manifest> diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png b/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png Binary files differdeleted file mode 100644 index 3a5c970..0000000 --- a/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png +++ /dev/null diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png b/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png Binary files differdeleted file mode 100644 index 4ffb1ee..0000000 --- a/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png +++ /dev/null diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/space.jpg b/libs/rs/java/Galaxy/res/drawable-hdpi/space.jpg Binary files differdeleted file mode 100644 index b61f6a3..0000000 --- a/libs/rs/java/Galaxy/res/drawable-hdpi/space.jpg +++ /dev/null diff --git a/libs/rs/java/Galaxy/res/raw/galaxy.c b/libs/rs/java/Galaxy/res/raw/galaxy.c deleted file mode 100644 index 9ff449f..0000000 --- a/libs/rs/java/Galaxy/res/raw/galaxy.c +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2009 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. - -#pragma version(1) -#pragma stateVertex(PVBackground) -#pragma stateFragment(PFBackground) -#pragma stateFragmentStore(PFSBackground) - -#define RSID_PARTICLES 1 - -#define PARTICLE_STRUCT_FIELDS_COUNT 6 -#define PARTICLE_STRUCT_ANGLE 0 -#define PARTICLE_STRUCT_DISTANCE 1 -#define PARTICLE_STRUCT_SPEED 2 -#define PARTICLE_STRUCT_RADIUS 3 -#define PARTICLE_STRUCT_S 4 -#define PARTICLE_STRUCT_T 5 - -#define RSID_PARTICLES_BUFFER 2 -#define PARTICLE_BUFFER_COMPONENTS_COUNT 5 - -#define PARTICLES_TEXTURES_COUNT 2 - -#define ELLIPSE_RATIO 0.892f - -void drawSpace(int width, int height) { - bindTexture(NAMED_PFBackground, 0, NAMED_TSpace); - drawQuadTexCoords( - 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, - width, 0.0f, 0.0f, 2.0f, 1.0f, - width, height, 0.0f, 2.0f, 0.0f, - 0.0f, height, 0.0f, 0.0f, 0.0f); -} - -void drawLights(int width, int height) { - float x = (width - 512.0f) * 0.5f; - float y = (height - 512.0f) * 0.5f; - - // increase the size of the texture by 5% on each side - x -= 512.0f * 0.05f; - - bindProgramFragment(NAMED_PFBackground); - bindTexture(NAMED_PFBackground, 0, NAMED_TLight1); - drawQuad(x + 512.0f * 1.1f, y , 0.0f, - x , y , 0.0f, - x , y + 512.0f, 0.0f, - x + 512.0f * 1.1f, y + 512.0f, 0.0f); -} - -void drawParticle(float *particle, float *particleBuffer, float w, float h) { - float distance = particle[PARTICLE_STRUCT_DISTANCE]; - float angle = particle[PARTICLE_STRUCT_ANGLE]; - float speed = particle[PARTICLE_STRUCT_SPEED]; - float r = particle[PARTICLE_STRUCT_RADIUS]; - - float a = angle + speed; - float x = distance * sinf_fast(a); - float y = distance * cosf_fast(a) * ELLIPSE_RATIO; - float s = particle[PARTICLE_STRUCT_S]; - float t = particle[PARTICLE_STRUCT_T]; - - float sX = t * x + s * y + w; - float sY = s * x - t * y + h; - - // lower left vertex of the particle's triangle - particleBuffer[1] = sX - r; // X - particleBuffer[2] = sY + r; // Y - - // lower right vertex of the particle's triangle - particleBuffer[6] = sX + r; // X - particleBuffer[7] = sY + r; // Y - - // upper middle vertex of the particle's triangle - particleBuffer[11] = sX; // X - particleBuffer[12] = sY - r; // Y - - particle[PARTICLE_STRUCT_ANGLE] = a; -} - -void drawParticles(int width, int height) { - bindProgramFragment(NAMED_PFLighting); - bindProgramFragmentStore(NAMED_PFSLights); - bindTexture(NAMED_PFLighting, 0, NAMED_TFlares); - - int radius = State_galaxyRadius; - int particlesCount = State_particlesCount; - - float *particle = loadArrayF(RSID_PARTICLES, 0); - float *particleBuffer = loadArrayF(RSID_PARTICLES_BUFFER, 0); - - float w = width * 0.5f; - float h = height * 0.5f; - - int i = 0; - for ( ; i < particlesCount; i++) { - drawParticle(particle, particleBuffer, w, h); - particle += PARTICLE_STRUCT_FIELDS_COUNT; - // each particle is a triangle (3 vertices) of 5 properties (ABGR, X, Y, S, T) - particleBuffer += 3 * PARTICLE_BUFFER_COMPONENTS_COUNT; - } - - uploadToBufferObject(NAMED_ParticlesBuffer); - drawSimpleMeshRange(NAMED_ParticlesMesh, 0, particlesCount * 3); -} - -int main(int index) { - int width = State_width; - int height = State_height; - - drawSpace(width, height); - drawParticles(width, height); - drawLights(width, height); - - return 1; -} diff --git a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java b/libs/rs/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java deleted file mode 100644 index 27d333c..0000000 --- a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/Galaxy.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -package com.android.galaxy.rs; - -import android.app.Activity; -import android.os.Bundle; - -public class Galaxy extends Activity { - private GalaxyView mView; - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - mView = new GalaxyView(this); - setContentView(mView); - } - - @Override - protected void onResume() { - super.onResume(); - mView.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - mView.onPause(); - - Runtime.getRuntime().exit(0); - } -}
\ No newline at end of file diff --git a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java b/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java deleted file mode 100644 index fae92f7..0000000 --- a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -package com.android.galaxy.rs; - -import android.content.res.Resources; -import android.renderscript.RenderScript; -import android.renderscript.ScriptC; -import android.renderscript.ProgramFragment; -import android.renderscript.ProgramStore; -import android.renderscript.ProgramVertex; -import android.renderscript.Allocation; -import android.renderscript.Sampler; -import android.renderscript.Element; -import android.renderscript.SimpleMesh; -import android.renderscript.Primitive; -import android.renderscript.Type; -import static android.renderscript.Sampler.Value.LINEAR; -import static android.renderscript.Sampler.Value.NEAREST; -import static android.renderscript.Sampler.Value.WRAP; -import static android.renderscript.ProgramStore.DepthFunc.*; -import static android.renderscript.ProgramStore.BlendDstFunc; -import static android.renderscript.ProgramStore.BlendSrcFunc; -import static android.renderscript.ProgramFragment.EnvMode.*; -import static android.renderscript.Element.*; -import android.graphics.BitmapFactory; -import android.graphics.Bitmap; -import static android.util.MathUtils.*; - -import java.util.TimeZone; - -@SuppressWarnings({"FieldCanBeLocal"}) -class GalaxyRS { - private static final int GALAXY_RADIUS = 300; - private static final int PARTICLES_COUNT = 12000; - private static final float ELLIPSE_TWIST = 0.023333333f; - - private static final int RSID_STATE = 0; - - private static final int TEXTURES_COUNT = 3; - private static final int RSID_TEXTURE_SPACE = 0; - private static final int RSID_TEXTURE_LIGHT1 = 1; - private static final int RSID_TEXTURE_FLARES = 2; - - private static final int RSID_PARTICLES = 1; - private static final int PARTICLE_STRUCT_FIELDS_COUNT = 6; - private static final int PARTICLE_STRUCT_ANGLE = 0; - private static final int PARTICLE_STRUCT_DISTANCE = 1; - private static final int PARTICLE_STRUCT_SPEED = 2; - private static final int PARTICLE_STRUCT_RADIUS = 3; - private static final int PARTICLE_STRUCT_S = 4; - private static final int PARTICLE_STRUCT_T = 5; - - private static final int RSID_PARTICLES_BUFFER = 2; - - private Resources mResources; - private RenderScript mRS; - - private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); - - private final int mWidth; - private final int mHeight; - - private ScriptC mScript; - private Sampler mSampler; - private Sampler mLightSampler; - private ProgramFragment mPfBackground; - private ProgramFragment mPfLighting; - private ProgramStore mPfsBackground; - private ProgramStore mPfsLights; - private ProgramVertex mPvBackground; - private ProgramVertex.MatrixAllocation mPvOrthoAlloc; - - private Allocation[] mTextures; - - private Type mStateType; - private Allocation mState; - private Allocation mParticles; - private Allocation mParticlesBuffer; - private SimpleMesh mParticlesMesh; - - private final float[] mFloatData5 = new float[5]; - - public GalaxyRS(int width, int height) { - mWidth = width; - mHeight = height; - mOptionsARGB.inScaled = false; - mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; - } - - public void init(RenderScript rs, Resources res) { - mRS = rs; - mResources = res; - initRS(); - } - - private void initRS() { - createProgramVertex(); - createProgramFragmentStore(); - createProgramFragment(); - createScriptStructures(); - loadTextures(); - - ScriptC.Builder sb = new ScriptC.Builder(mRS); - sb.setType(mStateType, "State", RSID_STATE); - sb.setScript(mResources, R.raw.galaxy); - sb.setRoot(true); - - mScript = sb.create(); - mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); - mScript.setTimeZone(TimeZone.getDefault().getID()); - - mScript.bindAllocation(mState, RSID_STATE); - mScript.bindAllocation(mParticles, RSID_PARTICLES); - mScript.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER); - - mRS.contextBindRootScript(mScript); - } - - private void createScriptStructures() { - createState(); - createParticlesMesh(); - createParticles(); - } - - private void createParticlesMesh() { - final Element.Builder elementBuilder = new Element.Builder(mRS); - elementBuilder.addUNorm8RGBA(); - elementBuilder.addFloatXY(); - elementBuilder.addFloatST(); - final Element vertexElement = elementBuilder.create(); - - final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS); - final int vertexSlot = meshBuilder.addVertexType(vertexElement, PARTICLES_COUNT * 3); - meshBuilder.setPrimitive(Primitive.TRIANGLE); - mParticlesMesh = meshBuilder.create(); - mParticlesMesh.setName("ParticlesMesh"); - - mParticlesBuffer = mParticlesMesh.createVertexAllocation(vertexSlot); - mParticlesBuffer.setName("ParticlesBuffer"); - mParticlesMesh.bindVertexAllocation(mParticlesBuffer, 0); - } - - static class GalaxyState { - public int frameCount; - public int width; - public int height; - public int particlesCount; - public int galaxyRadius; - } - - private void createState() { - GalaxyState state = new GalaxyState(); - state.width = mWidth; - state.height = mHeight; - state.particlesCount = PARTICLES_COUNT; - state.galaxyRadius = GALAXY_RADIUS; - - mStateType = Type.createFromClass(mRS, GalaxyState.class, 1, "GalaxyState"); - mState = Allocation.createTyped(mRS, mStateType); - mState.data(state); - } - - private void createParticles() { - final float[] particles = new float[PARTICLES_COUNT * PARTICLE_STRUCT_FIELDS_COUNT]; - - int bufferIndex = 0; - - for (int i = 0; i < particles.length; i += PARTICLE_STRUCT_FIELDS_COUNT) { - createParticle(particles, i, bufferIndex); - bufferIndex += 3; - } - - mParticles = Allocation.createSized(mRS, USER_FLOAT, particles.length); - mParticles.data(particles); - } - - @SuppressWarnings({"PointlessArithmeticExpression"}) - private void createParticle(float[] particles, int index, int bufferIndex) { - float d = abs(randomGauss()) * GALAXY_RADIUS / 2.0f + random(-4.0f, 4.0f); - float z = randomGauss() * 0.5f * 0.8f * ((GALAXY_RADIUS - d) / (float) GALAXY_RADIUS); - z += 1.0f; - float p = d * ELLIPSE_TWIST; - - particles[index + PARTICLE_STRUCT_ANGLE] = random(0.0f, (float) (Math.PI * 2.0)); - particles[index + PARTICLE_STRUCT_DISTANCE] = d; - particles[index + PARTICLE_STRUCT_SPEED] = random(0.0015f, 0.0025f) * - (0.5f + (0.5f * (float) GALAXY_RADIUS / d)) * 0.7f; - particles[index + PARTICLE_STRUCT_RADIUS] = z * random(1.2f, 2.1f); - particles[index + PARTICLE_STRUCT_S] = (float) Math.cos(p); - particles[index + PARTICLE_STRUCT_T] = (float) Math.sin(p); - - int red, green, blue; - if (d < GALAXY_RADIUS / 3.0f) { - red = (int) (220 + (d / (float) GALAXY_RADIUS) * 35); - green = 220; - blue = 220; - } else { - red = 180; - green = 180; - blue = (int) constrain(140 + (d / (float) GALAXY_RADIUS) * 115, 140, 255); - } - - final int color = red | green << 8 | blue << 16 | 0xff000000; - - final float[] floatData = mFloatData5; - final Allocation buffer = mParticlesBuffer; - - floatData[0] = Float.intBitsToFloat(color); - floatData[3] = 0.0f; - floatData[4] = 1.0f; - buffer.subData1D(bufferIndex, 1, floatData); - - bufferIndex++; - floatData[3] = 1.0f; - floatData[4] = 1.0f; - buffer.subData1D(bufferIndex, 1, floatData); - - bufferIndex++; - floatData[3] = 0.5f; - floatData[4] = 0.0f; - buffer.subData1D(bufferIndex, 1, floatData); - } - - private static float randomGauss() { - float x1; - float x2; - float w; - - do { - x1 = 2.0f * random(0.0f, 1.0f) - 1.0f; - x2 = 2.0f * random(0.0f, 1.0f) - 1.0f; - w = x1 * x1 + x2 * x2; - } while (w >= 1.0f); - - w = (float) Math.sqrt(-2.0 * log(w) / w); - return x1 * w; - } - - private void loadTextures() { - mTextures = new Allocation[TEXTURES_COUNT]; - - final Allocation[] textures = mTextures; - textures[RSID_TEXTURE_SPACE] = loadTexture(R.drawable.space, "TSpace"); - textures[RSID_TEXTURE_LIGHT1] = loadTextureARGB(R.drawable.light1, "TLight1"); - textures[RSID_TEXTURE_FLARES] = loadTextureARGB(R.drawable.flares, "TFlares"); - - final int count = textures.length; - for (int i = 0; i < count; i++) { - final Allocation texture = textures[i]; - texture.uploadToTexture(0); - } - } - - private Allocation loadTexture(int id, String name) { - final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, - id, RGB_565, false); - allocation.setName(name); - return allocation; - } - - private Allocation loadTextureARGB(int id, String name) { - Bitmap b = BitmapFactory.decodeResource(mResources, id, mOptionsARGB); - final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false); - allocation.setName(name); - return allocation; - } - - private void createProgramFragment() { - Sampler.Builder sampleBuilder = new Sampler.Builder(mRS); - sampleBuilder.setMin(LINEAR); - sampleBuilder.setMag(LINEAR); - sampleBuilder.setWrapS(WRAP); - sampleBuilder.setWrapT(WRAP); - mSampler = sampleBuilder.create(); - - ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null); - builder.setTexEnable(true, 0); - builder.setTexEnvMode(REPLACE, 0); - mPfBackground = builder.create(); - mPfBackground.setName("PFBackground"); - mPfBackground.bindSampler(mSampler, 0); - - sampleBuilder = new Sampler.Builder(mRS); - sampleBuilder.setMin(NEAREST); - sampleBuilder.setMag(NEAREST); - sampleBuilder.setWrapS(WRAP); - sampleBuilder.setWrapT(WRAP); - mLightSampler = sampleBuilder.create(); - - builder = new ProgramFragment.Builder(mRS, null, null); - builder.setTexEnable(true, 0); - builder.setTexEnvMode(MODULATE, 0); - mPfLighting = builder.create(); - mPfLighting.setName("PFLighting"); - mPfLighting.bindSampler(mLightSampler, 0); - } - - private void createProgramFragmentStore() { - ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null); - builder.setDepthFunc(ALWAYS); - builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); - builder.setDitherEnable(false); - mPfsBackground = builder.create(); - mPfsBackground.setName("PFSBackground"); - - builder = new ProgramStore.Builder(mRS, null, null); - builder.setDepthFunc(ALWAYS); - builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE); - builder.setDitherEnable(false); - mPfsLights = builder.create(); - mPfsLights.setName("PFSLights"); - } - - private void createProgramVertex() { - mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS); - //mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight); - mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight); - - ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null); - mPvBackground = builder.create(); - mPvBackground.bindAllocation(mPvOrthoAlloc); - mPvBackground.setName("PVBackground"); - } -} diff --git a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java b/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java deleted file mode 100644 index 4f6d3f0..0000000 --- a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyView.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2009 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. - */ - -package com.android.galaxy.rs; - -import android.content.Context; -import android.view.SurfaceHolder; -import android.renderscript.RenderScript; -import android.renderscript.RSSurfaceView; - -class GalaxyView extends RSSurfaceView { - public GalaxyView(Context context) { - super(context); - setFocusable(true); - setFocusableInTouchMode(true); - } - - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - super.surfaceChanged(holder, format, w, h); - - RenderScript RS = createRenderScript(); - GalaxyRS render = new GalaxyRS(w, h); - render.init(RS, getResources()); - } -} diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java index 3e1c54d..7524a0e 100644 --- a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java +++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java @@ -54,7 +54,7 @@ public class RolloView extends RSSurfaceView { public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { super.surfaceChanged(holder, format, w, h); - mRS = createRenderScript(); + mRS = createRenderScript(false); mRender = new RolloRS(); mRender.init(mRS, getResources(), w, h); } diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 413caab..52c2b78 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -18,6 +18,7 @@ #include "rsContext.h" #include "rsThreadIO.h" #include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> #include <GLES/gl.h> #include <GLES/glext.h> @@ -29,41 +30,63 @@ pthread_key_t Context::gThreadTLSKey = 0; void Context::initEGL() { - mNumConfigs = -1; - - EGLint s_configAttribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, -#if 1 - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, -#else - EGL_RED_SIZE, 5, - EGL_GREEN_SIZE, 6, - EGL_BLUE_SIZE, 5, -#endif - EGL_DEPTH_SIZE, 16, - EGL_NONE - }; - - mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - eglInitialize(mDisplay, &mMajorVersion, &mMinorVersion); - eglChooseConfig(mDisplay, s_configAttribs, &mConfig, 1, &mNumConfigs); - - if (mWndSurface) { - mSurface = eglCreateWindowSurface(mDisplay, mConfig, mWndSurface, - NULL); - } else { - mSurface = eglCreateWindowSurface(mDisplay, mConfig, - android_createDisplaySurface(), - NULL); - } + mEGL.mNumConfigs = -1; + EGLint configAttribs[128]; + EGLint *configAttribsPtr = configAttribs; + + memset(configAttribs, 0, sizeof(configAttribs)); + + configAttribsPtr[0] = EGL_SURFACE_TYPE; + configAttribsPtr[1] = EGL_WINDOW_BIT; + configAttribsPtr += 2; + + if (mUseDepth) { + configAttribsPtr[0] = EGL_DEPTH_SIZE; + configAttribsPtr[1] = 16; + configAttribsPtr += 2; + } + configAttribsPtr[0] = EGL_NONE; + rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint)))); + + mEGL.mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(mEGL.mDisplay, &mEGL.mMajorVersion, &mEGL.mMinorVersion); + + status_t err = EGLUtils::selectConfigForNativeWindow(mEGL.mDisplay, configAttribs, mWndSurface, &mEGL.mConfig); + if (err) { + LOGE("couldn't find an EGLConfig matching the screen format\n"); + } + //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs); + + if (mWndSurface) { + mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL); + } else { + mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, + android_createDisplaySurface(), + NULL); + } + + mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, NULL, NULL); + eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth); + eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight); + - mContext = eglCreateContext(mDisplay, mConfig, NULL, NULL); - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); - eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mWidth); - eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mHeight); + mGL.mVersion = glGetString(GL_VERSION); + mGL.mVendor = glGetString(GL_VENDOR); + mGL.mRenderer = glGetString(GL_RENDERER); + mGL.mExtensions = glGetString(GL_EXTENSIONS); + + //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion); + //LOGV("GL Version %s", mGL.mVersion); + //LOGV("GL Vendor %s", mGL.mVendor); + //LOGV("GL Renderer %s", mGL.mRenderer); + //LOGV("GL Extensions %s", mGL.mExtensions); + + if ((strlen((const char *)mGL.mVersion) < 12) || memcmp(mGL.mVersion, "OpenGL ES-CM", 12)) { + LOGE("Error, OpenGL ES Lite not supported"); + } else { + sscanf((const char *)mGL.mVersion + 13, "%i.%i", &mGL.mMajorVersion, &mGL.mMinorVersion); + } } bool Context::runScript(Script *s, uint32_t launchID) @@ -90,18 +113,20 @@ bool Context::runRootScript() //glColor4f(1,1,1,1); //glEnable(GL_LIGHT0); - glViewport(0, 0, mWidth, mHeight); - - glDepthMask(GL_TRUE); + glViewport(0, 0, mEGL.mWidth, mEGL.mHeight); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glClearColor(mRootScript->mEnviroment.mClearColor[0], mRootScript->mEnviroment.mClearColor[1], mRootScript->mEnviroment.mClearColor[2], mRootScript->mEnviroment.mClearColor[3]); - glClearDepthf(mRootScript->mEnviroment.mClearDepth); - glClear(GL_COLOR_BUFFER_BIT); - glClear(GL_DEPTH_BUFFER_BIT); + if (mUseDepth) { + glDepthMask(GL_TRUE); + glClearDepthf(mRootScript->mEnviroment.mClearDepth); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } else { + glClear(GL_COLOR_BUFFER_BIT); + } #if RS_LOG_TIMES timerSet(RS_TIMER_SCRIPT); @@ -156,13 +181,13 @@ void Context::timerPrint() void Context::setupCheck() { if (mFragmentStore.get()) { - mFragmentStore->setupGL(&mStateFragmentStore); + mFragmentStore->setupGL(this, &mStateFragmentStore); } if (mFragment.get()) { - mFragment->setupGL(&mStateFragment); + mFragment->setupGL(this, &mStateFragment); } if (mVertex.get()) { - mVertex->setupGL(&mStateVertex); + mVertex->setupGL(this, &mStateVertex); } } @@ -186,11 +211,11 @@ void * Context::threadProc(void *vrsc) LOGE("pthread_setspecific %i", status); } - rsc->mStateVertex.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); rsc->setVertex(NULL); - rsc->mStateFragment.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); rsc->setFragment(NULL); - rsc->mStateFragmentStore.init(rsc, rsc->mWidth, rsc->mHeight); + rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight); rsc->setFragmentStore(NULL); rsc->mRunning = true; @@ -204,7 +229,7 @@ void * Context::threadProc(void *vrsc) #if RS_LOG_TIMES rsc->timerSet(RS_TIMER_CLEAR_SWAP); #endif - eglSwapBuffers(rsc->mDisplay, rsc->mSurface); + eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); #if RS_LOG_TIMES rsc->timerSet(RS_TIMER_INTERNAL); rsc->timerPrint(); @@ -216,20 +241,23 @@ void * Context::threadProc(void *vrsc) } } + LOGV("RS Thread exiting"); glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(rsc->mDisplay, rsc->mSurface); - eglTerminate(rsc->mDisplay); + eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface); + eglTerminate(rsc->mEGL.mDisplay); rsc->objDestroyOOBRun(); + LOGV("RS Thread exited"); return NULL; } -Context::Context(Device *dev, Surface *sur) +Context::Context(Device *dev, Surface *sur, bool useDepth) { dev->addContext(this); mDev = dev; mRunning = false; mExit = false; + mUseDepth = useDepth; int status; pthread_attr_t threadAttr; @@ -270,9 +298,11 @@ Context::Context(Device *dev, Surface *sur) Context::~Context() { + LOGV("Context::~Context"); mExit = true; void *res; + mIO.shutdown(); int status = pthread_join(mThreadId, &res); objDestroyOOBRun(); @@ -284,17 +314,6 @@ Context::~Context() objDestroyOOBDestroy(); } -void Context::swapBuffers() -{ - eglSwapBuffers(mDisplay, mSurface); -} - -void rsContextSwap(RsContext vrsc) -{ - Context *rsc = static_cast<Context *>(vrsc); - rsc->swapBuffers(); -} - void Context::setRootScript(Script *s) { mRootScript.set(s); @@ -520,10 +539,10 @@ void rsi_ContextSetDefineI32(Context *rsc, const char* name, int32_t value) } -RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version) +RsContext rsContextCreate(RsDevice vdev, void *sur, uint32_t version, bool useDepth) { Device * dev = static_cast<Device *>(vdev); - Context *rsc = new Context(dev, (Surface *)sur); + Context *rsc = new Context(dev, (Surface *)sur, useDepth); return rsc; } diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index ca67e40..c58a88c 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -49,7 +49,7 @@ namespace renderscript { class Context { public: - Context(Device *, Surface *); + Context(Device *, Surface *, bool useDepth); ~Context(); static pthread_key_t gThreadTLSKey; @@ -111,8 +111,8 @@ public: mFloatDefines.add(String8(name), value); } - uint32_t getWidth() const {return mWidth;} - uint32_t getHeight() const {return mHeight;} + uint32_t getWidth() const {return mEGL.mWidth;} + uint32_t getHeight() const {return mEGL.mHeight;} ThreadIO mIO; @@ -132,21 +132,38 @@ public: void timerSet(Timers); void timerPrint(); + bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); } + bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; } + protected: Device *mDev; - EGLint mNumConfigs; - EGLint mMajorVersion; - EGLint mMinorVersion; - EGLConfig mConfig; - EGLContext mContext; - EGLSurface mSurface; - EGLint mWidth; - EGLint mHeight; - EGLDisplay mDisplay; + struct { + EGLint mNumConfigs; + EGLint mMajorVersion; + EGLint mMinorVersion; + EGLConfig mConfig; + EGLContext mContext; + EGLSurface mSurface; + EGLint mWidth; + EGLint mHeight; + EGLDisplay mDisplay; + } mEGL; + + struct { + const uint8_t * mVendor; + const uint8_t * mRenderer; + const uint8_t * mVersion; + const uint8_t * mExtensions; + + uint32_t mMajorVersion; + uint32_t mMinorVersion; + + } mGL; bool mRunning; bool mExit; + bool mUseDepth; pthread_t mThreadId; diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index c3fee54..0c40389 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -25,6 +25,16 @@ LocklessCommandFifo::LocklessCommandFifo() LocklessCommandFifo::~LocklessCommandFifo() { + if (!mInShutdown) { + shutdown(); + } + free(mBuffer); +} + +void LocklessCommandFifo::shutdown() +{ + mInShutdown = true; + mSignalToWorker.set(); } bool LocklessCommandFifo::init(uint32_t sizeInBytes) @@ -42,6 +52,7 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes) return false; } + mInShutdown = false; mSize = sizeInBytes; mPut = mBuffer; mGet = mBuffer; @@ -50,7 +61,7 @@ bool LocklessCommandFifo::init(uint32_t sizeInBytes) return true; } -uint32_t LocklessCommandFifo::getFreeSpace() const +uint32_t LocklessCommandFifo::getFreeSpace() const { int32_t freeSpace = 0; //dumpState("getFreeSpace"); @@ -115,7 +126,7 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) { while(1) { //dumpState("get"); - while(isEmpty()) { + while(isEmpty() && !mInShutdown) { mSignalToControl.set(); mSignalToWorker.wait(); } @@ -126,7 +137,7 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData) // non-zero command is valid return mGet+4; } - + // zero command means reset to beginning. mGet = mBuffer; } @@ -161,7 +172,7 @@ void LocklessCommandFifo::makeSpace(uint32_t bytes) while(getFreeSpace() < bytes) { sleep(1); } - + } void LocklessCommandFifo::dumpState(const char *s) const diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h index abeddf7..d0a4356 100644 --- a/libs/rs/rsLocklessFifo.h +++ b/libs/rs/rsLocklessFifo.h @@ -25,13 +25,14 @@ namespace android { // A simple FIFO to be used as a producer / consumer between two // threads. One is writer and one is reader. The common cases -// will not require locking. It is not threadsafe for multiple +// will not require locking. It is not threadsafe for multiple // readers or writers by design. -class LocklessCommandFifo +class LocklessCommandFifo { public: bool init(uint32_t size); + void shutdown(); LocklessCommandFifo(); ~LocklessCommandFifo(); @@ -59,6 +60,7 @@ protected: uint8_t * mBuffer; uint8_t * mEnd; uint8_t mSize; + bool mInShutdown; Signal mSignalToWorker; Signal mSignalToControl; diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp index 6a5b7d8..07bbc1e 100644 --- a/libs/rs/rsObjectBase.cpp +++ b/libs/rs/rsObjectBase.cpp @@ -43,6 +43,11 @@ void ObjectBase::decRef() const mRefCount --; //LOGV("ObjectBase %p dec ref %i", this, mRefCount); if (!mRefCount) { + if (mName) { + LOGV("Deleting RS object %p, name %s", this, mName); + } else { + LOGV("Deleting RS object %p, no name", this); + } delete this; } } diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 6606daa..18eacfb 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -47,9 +47,3 @@ void Program::checkUpdatedAllocation(const Allocation *alloc) } } -void Program::setupGL() -{ - -} - - diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index 251072f..bb3d9ac 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -32,11 +32,7 @@ public: Program(Element *in, Element *out); virtual ~Program(); - void bindAllocation(Allocation *); - - virtual void setupGL(); - void checkUpdatedAllocation(const Allocation *); protected: diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 4ef6835..654974f 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -40,7 +40,7 @@ ProgramFragment::~ProgramFragment() { } -void ProgramFragment::setupGL(ProgramFragmentState *state) +void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state) { if ((state->mLast.get() == this) && !mDirty) { return; @@ -55,7 +55,9 @@ void ProgramFragment::setupGL(ProgramFragmentState *state) } glEnable(GL_TEXTURE_2D); - //glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable); + if (rsc->checkVersion1_1()) { + glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable); + } glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID()); switch(mEnvModes[ct]) { diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h index bd45342..51117eb 100644 --- a/libs/rs/rsProgramFragment.h +++ b/libs/rs/rsProgramFragment.h @@ -35,7 +35,7 @@ public: ProgramFragment(Element *in, Element *out, bool pointSpriteEnable); virtual ~ProgramFragment(); - virtual void setupGL(ProgramFragmentState *); + virtual void setupGL(const Context *, ProgramFragmentState *); diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp index 99eed16..36ec615 100644 --- a/libs/rs/rsProgramFragmentStore.cpp +++ b/libs/rs/rsProgramFragmentStore.cpp @@ -48,7 +48,7 @@ ProgramFragmentStore::~ProgramFragmentStore() { } -void ProgramFragmentStore::setupGL(ProgramFragmentStoreState *state) +void ProgramFragmentStore::setupGL(const Context *rsc, ProgramFragmentStoreState *state) { if (state->mLast.get() == this) { return; diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h index 0de5c3a..e646e03 100644 --- a/libs/rs/rsProgramFragmentStore.h +++ b/libs/rs/rsProgramFragmentStore.h @@ -31,7 +31,7 @@ public: ProgramFragmentStore(Element *in, Element *out); virtual ~ProgramFragmentStore(); - virtual void setupGL(ProgramFragmentStoreState *); + virtual void setupGL(const Context *, ProgramFragmentStoreState *); void setDepthFunc(RsDepthFunc); void setDepthMask(bool); diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 6ef5456..dc57d34 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -44,7 +44,7 @@ static void logMatrix(const char *txt, const float *f) LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]); } -void ProgramVertex::setupGL(ProgramVertexState *state) +void ProgramVertex::setupGL(const Context *rsc, ProgramVertexState *state) { if ((state->mLast.get() == this) && !mDirty) { return; diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index c9ce7aa..523c3ed 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -33,7 +33,7 @@ public: ProgramVertex(Element *in, Element *out); virtual ~ProgramVertex(); - virtual void setupGL(ProgramVertexState *state); + virtual void setupGL(const Context *rsc, ProgramVertexState *state); void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;} diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index db4fd09..9419829 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -267,7 +267,7 @@ void ScriptCState::appendTypes(String8 *str) tmp.append(c->getComponentName()); sprintf(buf, " %i\n", ct2); tmp.append(buf); - LOGD(tmp); + //LOGD(tmp); str->append(tmp); } } @@ -295,7 +295,7 @@ void ScriptCState::appendTypes(String8 *str) sprintf(buf, "%i, %i)\n", ct, ct2); tmp.append(buf); - LOGD(tmp); + //LOGD(tmp); str->append(tmp); } } diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 4a1dbbb..db4bb81 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -30,6 +30,11 @@ ThreadIO::~ThreadIO() { } +void ThreadIO::shutdown() +{ + mToCore.shutdown(); +} + bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) { bool ret = false; diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index 4aab1b4..1f6a0c2 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -31,6 +31,8 @@ public: ThreadIO(); ~ThreadIO(); + void shutdown(); + // Plays back commands from the client. // Returns true if any commands were processed. bool playCoreCommands(Context *con, bool waitForCommand); |
