diff --git a/BUILD.gn b/BUILD.gn index 4758f52551..e687a055ae 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -360,14 +360,11 @@ optional("android_utils") { "client_utils/android/BRDAllocator.h", "client_utils/android/BitmapRegionDecoder.h", "client_utils/android/FrontBufferedStream.h", - "client_utils/android/SkCamera.h", - "client_utils/android/View3D.h", ] public_defines = [ "SK_ENABLE_ANDROID_UTILS" ] sources = [ "client_utils/android/BitmapRegionDecoder.cpp", "client_utils/android/FrontBufferedStream.cpp", - "client_utils/android/View3D.cpp", ] } diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt index 3788928892..5feec5ce46 100644 --- a/RELEASE_NOTES.txt +++ b/RELEASE_NOTES.txt @@ -2,12 +2,6 @@ Skia Graphics Release Notes This file includes a list of high level updates for each milestone release. -Milestone 103 -------------- - * SkCamera, SkPatch3D, Sk3DView have been moved to client_utils/android and renamed to - Camera, Patch3D, and View3D respectively. - - Milestone 102 ------------- * Add glGetFloatv and glSamplerParameterf to GrGLInterface. diff --git a/client_utils/README.md b/client_utils/README.md deleted file mode 100644 index e1a28b1d15..0000000000 --- a/client_utils/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This folder contains code that at one point may have been part of the Skia API, but ended up -being very specific to a single client. Thus, we removed it from our more general purpose API, -but kept the functionality here for the one client that needs it. \ No newline at end of file diff --git a/client_utils/android/SkCamera.h b/client_utils/android/SkCamera.h deleted file mode 100644 index 65dce77a23..0000000000 --- a/client_utils/android/SkCamera.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2022 Google LLC - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "client_utils/android/View3D.h" - -// Temporary, until Android updates to the new API -using Sk3DView = android::skia::View3D; diff --git a/gn/samples.gni b/gn/samples.gni index ea54c8eddd..28748beccd 100644 --- a/gn/samples.gni +++ b/gn/samples.gni @@ -20,6 +20,7 @@ samples_sources = [ "$_samplecode/SampleArc.cpp", "$_samplecode/SampleAtlas.cpp", "$_samplecode/SampleAudio.cpp", + "$_samplecode/SampleCamera.cpp", "$_samplecode/SampleChart.cpp", "$_samplecode/SampleChineseFling.cpp", "$_samplecode/SampleCircle.cpp", diff --git a/gn/utils.gni b/gn/utils.gni index 5b628d04dd..97f5ed6629 100644 --- a/gn/utils.gni +++ b/gn/utils.gni @@ -10,6 +10,7 @@ _include = get_path_info("../include", "abspath") skia_utils_public = [ "$_include/utils/SkAnimCodecPlayer.h", "$_include/utils/SkBase64.h", + "$_include/utils/SkCamera.h", "$_include/utils/SkCanvasStateUtils.h", "$_include/utils/SkCustomTypeface.h", "$_include/utils/SkEventTracer.h", @@ -34,6 +35,7 @@ skia_utils_sources = [ "$_src/utils/SkBlitterTrace.h", "$_src/utils/SkBlitterTraceCommon.h", "$_src/utils/SkCallableTraits.h", + "$_src/utils/SkCamera.cpp", "$_src/utils/SkCanvasStack.cpp", "$_src/utils/SkCanvasStack.h", "$_src/utils/SkCanvasStateUtils.cpp", diff --git a/include/utils/BUILD.bazel b/include/utils/BUILD.bazel index f38b6e33c0..58d0757421 100644 --- a/include/utils/BUILD.bazel +++ b/include/utils/BUILD.bazel @@ -16,6 +16,17 @@ generated_cc_atom( deps = ["//include/core:SkTypes_hdr"], ) +generated_cc_atom( + name = "SkCamera_hdr", + hdrs = ["SkCamera.h"], + visibility = ["//:__subpackages__"], + deps = [ + "//include/core:SkM44_hdr", + "//include/core:SkMatrix_hdr", + "//include/private:SkNoncopyable_hdr", + ], +) + generated_cc_atom( name = "SkCanvasStateUtils_hdr", hdrs = ["SkCanvasStateUtils.h"], diff --git a/client_utils/android/View3D.h b/include/utils/SkCamera.h similarity index 60% rename from client_utils/android/View3D.h rename to include/utils/SkCamera.h index 98751b912b..51a7d4d6b0 100644 --- a/client_utils/android/View3D.h +++ b/include/utils/SkCamera.h @@ -7,23 +7,27 @@ // Inspired by Rob Johnson's most excellent QuickDraw GX sample code -#ifndef View3D_DEFINED -#define View3D_DEFINED +#ifndef SkCamera_DEFINED +#define SkCamera_DEFINED #include "include/core/SkM44.h" +#include "include/core/SkMatrix.h" +#include "include/private/SkNoncopyable.h" + +// NOTE -- This entire header / impl is deprecated, and will be removed from Skia soon. +// +// Skia now has support for a 4x matrix (SkM44) in SkCanvas. +// class SkCanvas; -class SkMatrix; -namespace android { -namespace skia { - -class Patch3D { -private: - Patch3D(); +// DEPRECATED +class SkPatch3D { +public: + SkPatch3D(); void reset(); - void transform(const SkM44&, Patch3D* dst = nullptr) const; + void transform(const SkM44&, SkPatch3D* dst = nullptr) const; // dot a unit vector with the patch's normal SkScalar dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const; @@ -31,38 +35,44 @@ private: return this->dotWith(v.x, v.y, v.z); } - SkV3 fOrigin; - SkV3 fU, fV; + // deprecated, but still here for animator (for now) + void rotate(SkScalar /*x*/, SkScalar /*y*/, SkScalar /*z*/) {} + void rotateDegrees(SkScalar /*x*/, SkScalar /*y*/, SkScalar /*z*/) {} - friend class Camera3D; - friend class View3D; +private: +public: // make public for SkDraw3D for now + SkV3 fU, fV; + SkV3 fOrigin; + + friend class SkCamera3D; }; -class Camera3D { -private: - Camera3D(); +// DEPRECATED +class SkCamera3D { +public: + SkCamera3D(); void reset(); void update(); - void patchToMatrix(const Patch3D&, SkMatrix* matrix) const; + void patchToMatrix(const SkPatch3D&, SkMatrix* matrix) const; SkV3 fLocation; // origin of the camera's space SkV3 fAxis; // view direction SkV3 fZenith; // up direction SkV3 fObserver; // eye position (may not be the same as the origin) +private: mutable SkMatrix fOrientation; mutable bool fNeedToUpdate; void doUpdate() const; - - friend class View3D; }; -class View3D { +// DEPRECATED +class SK_API Sk3DView : SkNoncopyable { public: - View3D(); - ~View3D(); + Sk3DView(); + ~Sk3DView(); void save(); void restore(); @@ -72,10 +82,12 @@ public: void rotateY(SkScalar deg); void rotateZ(SkScalar deg); +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK void setCameraLocation(SkScalar x, SkScalar y, SkScalar z); SkScalar getCameraLocationX() const; SkScalar getCameraLocationY() const; SkScalar getCameraLocationZ() const; +#endif void getMatrix(SkMatrix*) const; void applyToCanvas(SkCanvas*) const; @@ -87,13 +99,9 @@ private: Rec* fNext; SkM44 fMatrix; }; - Rec* fRec; - Rec fInitialRec; - Camera3D fCamera; - - View3D(const View3D&) = delete; - View3D& operator=(const View3D&) = delete; + Rec* fRec; + Rec fInitialRec; + SkCamera3D fCamera; }; -} // namespace skia -} // namespace android -#endif // View3D_DEFINED + +#endif diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp index a98c36fcd2..50c626e7b7 100644 --- a/samplecode/SampleAndroidShadows.cpp +++ b/samplecode/SampleAndroidShadows.cpp @@ -10,6 +10,7 @@ #include "include/core/SkPath.h" #include "include/core/SkPoint3.h" #include "include/pathops/SkPathOps.h" +#include "include/utils/SkCamera.h" #include "include/utils/SkShadowUtils.h" #include "samplecode/Sample.h" #include "src/core/SkBlurMask.h" @@ -17,10 +18,6 @@ #include "tools/ToolUtils.h" #include "tools/timer/TimeUtils.h" -#ifdef SK_ENABLE_ANDROID_UTILS -#include "client_utils/android/View3D.h" -#endif - //////////////////////////////////////////////////////////////////////////// class ShadowsView : public Sample { @@ -268,13 +265,12 @@ class ShadowsView : public Sample { this->drawShadowedPath(canvas, tmpPath, zPlaneParams, paint, .1f, lightPos, kLightWidth, .5f); -#ifdef SK_ENABLE_ANDROID_UTILS // perspective paths SkPoint pivot = SkPoint::Make(fWideRectPath.getBounds().width()/2, fWideRectPath.getBounds().height()/2); SkPoint translate = SkPoint::Make(100, 450); paint.setColor(SK_ColorWHITE); - android::skia::View3D view; + Sk3DView view; view.save(); view.rotateX(fAnimAngle); SkMatrix persp; @@ -319,7 +315,6 @@ class ShadowsView : public Sample { std::max(1.0f, 8 + fZDelta) + SkScalarSin(radians)*pivot.fX); this->drawShadowedPath(canvas, fStarPath, zPlaneParams, paint, .1f, lightPos, kLightWidth, .5f); -#endif } bool onAnimate(double nanos) override { diff --git a/samplecode/SampleCamera.cpp b/samplecode/SampleCamera.cpp new file mode 100644 index 0000000000..41da126e57 --- /dev/null +++ b/samplecode/SampleCamera.cpp @@ -0,0 +1,75 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "include/core/SkCanvas.h" +#include "include/core/SkImage.h" +#include "include/core/SkShader.h" +#include "include/core/SkString.h" +#include "include/utils/SkCamera.h" +#include "samplecode/DecodeFile.h" +#include "samplecode/Sample.h" +#include "src/effects/SkEmbossMaskFilter.h" +#include "tools/Resources.h" +#include "tools/timer/TimeUtils.h" + +namespace { +class CameraView : public Sample { + SkTArray> fShaders; + int fShaderIndex = 0; + bool fFrontFace = false; + SkScalar fRX = 0; + SkScalar fRY = 0; + + SkString name() override { return SkString("Camera"); } + + void onOnceBeforeDraw() override { + for (const char* resource : { + "images/mandrill_512_q075.jpg", + "images/dog.jpg", + "images/gamut.png", + }) { + SkBitmap bm; + if (GetResourceAsBitmap(resource, &bm)) { + SkRect src = { 0, 0, SkIntToScalar(bm.width()), SkIntToScalar(bm.height()) }; + SkRect dst = { -150, -150, 150, 150 }; + fShaders.push_back(bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear), + SkMatrix::RectToRect(src, dst))); + } + } + this->setBGColor(0xFFDDDDDD); + } + + void onDrawContent(SkCanvas* canvas) override { + if (fShaders.count() > 0) { + canvas->translate(this->width()/2, this->height()/2); + + Sk3DView view; + view.rotateX(fRX); + view.rotateY(fRY); + view.applyToCanvas(canvas); + + bool frontFace = view.dotWithNormal(0, 0, SK_Scalar1) < 0; + if (frontFace != fFrontFace) { + fFrontFace = frontFace; + fShaderIndex = (fShaderIndex + 1) % fShaders.count(); + } + + SkPaint paint; + paint.setAntiAlias(true); + paint.setShader(fShaders[fShaderIndex]); + SkRect r = { -150, -150, 150, 150 }; + canvas->drawRoundRect(r, 30, 30, paint); + } + } + + bool onAnimate(double nanos) override { + fRY = nanos ? TimeUtils::Scaled(1e-9 * nanos, 90, 360) : 0; + return true; + } +}; +} // namespace +DEF_SAMPLE( return new CameraView(); ) diff --git a/samplecode/SampleLayers.cpp b/samplecode/SampleLayers.cpp index b07ce0d4fc..c22857817c 100644 --- a/samplecode/SampleLayers.cpp +++ b/samplecode/SampleLayers.cpp @@ -16,6 +16,7 @@ #include "include/core/SkTime.h" #include "include/core/SkTypeface.h" #include "include/effects/SkGradientShader.h" +#include "include/utils/SkCamera.h" #include "samplecode/Sample.h" #include "src/utils/SkUTF.h" diff --git a/samplecode/SampleMaterialShadows.cpp b/samplecode/SampleMaterialShadows.cpp index 896699fe37..8cb951fa28 100644 --- a/samplecode/SampleMaterialShadows.cpp +++ b/samplecode/SampleMaterialShadows.cpp @@ -10,6 +10,7 @@ #include "include/core/SkPath.h" #include "include/core/SkPoint3.h" #include "include/pathops/SkPathOps.h" +#include "include/utils/SkCamera.h" #include "include/utils/SkShadowUtils.h" #include "samplecode/Sample.h" #include "src/core/SkBlurMask.h" diff --git a/samplecode/SampleShadowUtils.cpp b/samplecode/SampleShadowUtils.cpp index ecf3f05bce..e3138750d9 100644 --- a/samplecode/SampleShadowUtils.cpp +++ b/samplecode/SampleShadowUtils.cpp @@ -10,6 +10,7 @@ #include "include/core/SkPath.h" #include "include/core/SkPoint3.h" #include "include/pathops/SkPathOps.h" +#include "include/utils/SkCamera.h" #include "include/utils/SkShadowUtils.h" #include "samplecode/Sample.h" #include "src/core/SkBlurMask.h" diff --git a/src/utils/BUILD.bazel b/src/utils/BUILD.bazel index 586a06a838..3676029e51 100644 --- a/src/utils/BUILD.bazel +++ b/src/utils/BUILD.bazel @@ -8,6 +8,7 @@ cc_library( deps = [ ":SkAnimCodecPlayer_src", ":SkBase64_src", + ":SkCamera_src", ":SkCanvasStack_src", ":SkCanvasStateUtils_src", ":SkCharToGlyphCache_src", @@ -95,6 +96,16 @@ generated_cc_atom( visibility = ["//:__subpackages__"], ) +generated_cc_atom( + name = "SkCamera_src", + srcs = ["SkCamera.cpp"], + visibility = ["//:__subpackages__"], + deps = [ + "//include/core:SkCanvas_hdr", + "//include/utils:SkCamera_hdr", + ], +) + generated_cc_atom( name = "SkCanvasStack_hdr", hdrs = ["SkCanvasStack.h"], diff --git a/client_utils/android/View3D.cpp b/src/utils/SkCamera.cpp similarity index 83% rename from client_utils/android/View3D.cpp rename to src/utils/SkCamera.cpp index 8279949d47..45e216edb2 100644 --- a/client_utils/android/View3D.cpp +++ b/src/utils/SkCamera.cpp @@ -5,13 +5,7 @@ * found in the LICENSE file. */ -#include "client_utils/android/View3D.h" - -#include "include/core/SkCanvas.h" -#include "include/core/SkMatrix.h" - -namespace android { -namespace skia { +#include "include/utils/SkCamera.h" static SkScalar SkScalarDotDiv(int count, const SkScalar a[], int step_a, const SkScalar b[], int step_b, @@ -27,19 +21,19 @@ static SkScalar SkScalarDotDiv(int count, const SkScalar a[], int step_a, /////////////////////////////////////////////////////////////////////////////// -Patch3D::Patch3D() { +SkPatch3D::SkPatch3D() { this->reset(); } -void Patch3D::reset() { +void SkPatch3D::reset() { fOrigin = {0, 0, 0}; fU = {SK_Scalar1, 0, 0}; fV = {0, -SK_Scalar1, 0}; } -void Patch3D::transform(const SkM44& m, Patch3D* dst) const { +void SkPatch3D::transform(const SkM44& m, SkPatch3D* dst) const { if (dst == nullptr) { - dst = (Patch3D*)this; + dst = (SkPatch3D*)this; } dst->fU = m * fU; dst->fV = m * fV; @@ -47,7 +41,7 @@ void Patch3D::transform(const SkM44& m, Patch3D* dst) const { dst->fOrigin = {x, y, z}; } -SkScalar Patch3D::dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const { +SkScalar SkPatch3D::dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const { SkScalar cx = fU.y * fV.z - fU.z * fV.y; SkScalar cy = fU.z * fV.x - fU.x * fV.y; SkScalar cz = fU.x * fV.y - fU.y * fV.x; @@ -57,11 +51,11 @@ SkScalar Patch3D::dotWith(SkScalar dx, SkScalar dy, SkScalar dz) const { /////////////////////////////////////////////////////////////////////////////// -Camera3D::Camera3D() { +SkCamera3D::SkCamera3D() { this->reset(); } -void Camera3D::reset() { +void SkCamera3D::reset() { fLocation = {0, 0, -SkIntToScalar(576)}; // 8 inches backward fAxis = {0, 0, SK_Scalar1}; // forward fZenith = {0, -SK_Scalar1, 0}; // up @@ -71,11 +65,11 @@ void Camera3D::reset() { fNeedToUpdate = true; } -void Camera3D::update() { +void SkCamera3D::update() { fNeedToUpdate = true; } -void Camera3D::doUpdate() const { +void SkCamera3D::doUpdate() const { SkV3 axis, zenith, cross; // construct a orthonormal basis of cross (x), zenith (y), and axis (z) @@ -116,7 +110,7 @@ void Camera3D::doUpdate() const { } } -void Camera3D::patchToMatrix(const Patch3D& quilt, SkMatrix* matrix) const { +void SkCamera3D::patchToMatrix(const SkPatch3D& quilt, SkMatrix* matrix) const { if (fNeedToUpdate) { this->doUpdate(); fNeedToUpdate = false; @@ -155,11 +149,11 @@ void Camera3D::patchToMatrix(const Patch3D& quilt, SkMatrix* matrix) const { /////////////////////////////////////////////////////////////////////////////// -View3D::View3D() { +Sk3DView::Sk3DView() { fRec = &fInitialRec; } -View3D::~View3D() { +Sk3DView::~Sk3DView() { Rec* rec = fRec; while (rec != &fInitialRec) { Rec* next = rec->fNext; @@ -168,21 +162,22 @@ View3D::~View3D() { } } -void View3D::save() { +void Sk3DView::save() { Rec* rec = new Rec; rec->fNext = fRec; rec->fMatrix = fRec->fMatrix; fRec = rec; } -void View3D::restore() { +void Sk3DView::restore() { SkASSERT(fRec != &fInitialRec); Rec* next = fRec->fNext; delete fRec; fRec = next; } -void View3D::setCameraLocation(SkScalar x, SkScalar y, SkScalar z) { +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK +void Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z) { // the camera location is passed in inches, set in pt SkScalar lz = z * 72.0f; fCamera.fLocation = {x * 72.0f, y * 72.0f, lz}; @@ -191,54 +186,54 @@ void View3D::setCameraLocation(SkScalar x, SkScalar y, SkScalar z) { } -SkScalar View3D::getCameraLocationX() const { +SkScalar Sk3DView::getCameraLocationX() const { return fCamera.fLocation.x / 72.0f; } -SkScalar View3D::getCameraLocationY() const { +SkScalar Sk3DView::getCameraLocationY() const { return fCamera.fLocation.y / 72.0f; } -SkScalar View3D::getCameraLocationZ() const { +SkScalar Sk3DView::getCameraLocationZ() const { return fCamera.fLocation.z / 72.0f; } +#endif -void View3D::translate(SkScalar x, SkScalar y, SkScalar z) { +void Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z) { fRec->fMatrix.preTranslate(x, y, z); } -void View3D::rotateX(SkScalar deg) { +void Sk3DView::rotateX(SkScalar deg) { fRec->fMatrix.preConcat(SkM44::Rotate({1, 0, 0}, deg * SK_ScalarPI / 180)); } -void View3D::rotateY(SkScalar deg) { +void Sk3DView::rotateY(SkScalar deg) { fRec->fMatrix.preConcat(SkM44::Rotate({0,-1, 0}, deg * SK_ScalarPI / 180)); } -void View3D::rotateZ(SkScalar deg) { +void Sk3DView::rotateZ(SkScalar deg) { fRec->fMatrix.preConcat(SkM44::Rotate({0, 0, 1}, deg * SK_ScalarPI / 180)); } -SkScalar View3D::dotWithNormal(SkScalar x, SkScalar y, SkScalar z) const { - Patch3D patch; +SkScalar Sk3DView::dotWithNormal(SkScalar x, SkScalar y, SkScalar z) const { + SkPatch3D patch; patch.transform(fRec->fMatrix); return patch.dotWith(x, y, z); } -void View3D::getMatrix(SkMatrix* matrix) const { +void Sk3DView::getMatrix(SkMatrix* matrix) const { if (matrix != nullptr) { - Patch3D patch; + SkPatch3D patch; patch.transform(fRec->fMatrix); fCamera.patchToMatrix(patch, matrix); } } -void View3D::applyToCanvas(SkCanvas* canvas) const { +#include "include/core/SkCanvas.h" + +void Sk3DView::applyToCanvas(SkCanvas* canvas) const { SkMatrix matrix; this->getMatrix(&matrix); canvas->concat(matrix); } - -} // namespace skia -} // namespace android