Merge "Revert "Tonemap in RecordingCanvas""
This commit is contained in:
@@ -212,9 +212,9 @@ public abstract class ColorSpace {
|
||||
new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4);
|
||||
private static final Rgb.TransferParameters BT2020_HLG_TRANSFER_PARAMETERS =
|
||||
new Rgb.TransferParameters(2.0f, 2.0f, 1 / 0.17883277f,
|
||||
0.28466892f, 0.5599107f, -11 / 12.0f, -3.0f, true);
|
||||
0.28466892f, 0.5599107f, 0.0f, -3.0f, true);
|
||||
private static final Rgb.TransferParameters BT2020_PQ_TRANSFER_PARAMETERS =
|
||||
new Rgb.TransferParameters(-107 / 128.0f, 1.0f, 32 / 2523.0f,
|
||||
new Rgb.TransferParameters(107 / 128.0f, 1.0f, 32 / 2523.0f,
|
||||
2413 / 128.0f, -2392 / 128.0f, 8192 / 1305.0f, -2.0f, true);
|
||||
|
||||
// See static initialization block next to #get(Named)
|
||||
|
||||
@@ -551,7 +551,6 @@ cc_defaults {
|
||||
"RootRenderNode.cpp",
|
||||
"SkiaCanvas.cpp",
|
||||
"SkiaInterpolator.cpp",
|
||||
"Tonemapper.cpp",
|
||||
"VectorDrawable.cpp",
|
||||
],
|
||||
|
||||
@@ -610,6 +609,7 @@ cc_defaults {
|
||||
"ProfileData.cpp",
|
||||
"ProfileDataContainer.cpp",
|
||||
"Readback.cpp",
|
||||
"Tonemapper.cpp",
|
||||
"TreeInfo.cpp",
|
||||
"WebViewFunctorManager.cpp",
|
||||
"protos/graphicsstats.proto",
|
||||
|
||||
@@ -45,4 +45,4 @@ bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette pale
|
||||
SkColor transformColor(ColorTransform transform, SkColor color);
|
||||
SkColor transformColorInverse(ColorTransform transform, SkColor color);
|
||||
|
||||
} // namespace android::uirenderer
|
||||
} // namespace android::uirenderer;
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "SkRegion.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkVertices.h"
|
||||
#include "Tonemapper.h"
|
||||
#include "VectorDrawable.h"
|
||||
#include "include/gpu/GpuTypes.h" // from Skia
|
||||
#include "include/gpu/GrDirectContext.h"
|
||||
@@ -345,9 +344,7 @@ struct DrawImage final : Op {
|
||||
SkPaint paint;
|
||||
BitmapPalette palette;
|
||||
void draw(SkCanvas* c, const SkMatrix&) const {
|
||||
SkPaint newPaint = paint;
|
||||
tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
|
||||
c->drawImage(image.get(), x, y, sampling, &newPaint);
|
||||
c->drawImage(image.get(), x, y, sampling, &paint);
|
||||
}
|
||||
};
|
||||
struct DrawImageRect final : Op {
|
||||
@@ -369,9 +366,7 @@ struct DrawImageRect final : Op {
|
||||
SkCanvas::SrcRectConstraint constraint;
|
||||
BitmapPalette palette;
|
||||
void draw(SkCanvas* c, const SkMatrix&) const {
|
||||
SkPaint newPaint = paint;
|
||||
tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
|
||||
c->drawImageRect(image.get(), src, dst, sampling, &newPaint, constraint);
|
||||
c->drawImageRect(image.get(), src, dst, sampling, &paint, constraint);
|
||||
}
|
||||
};
|
||||
struct DrawImageLattice final : Op {
|
||||
@@ -404,10 +399,8 @@ struct DrawImageLattice final : Op {
|
||||
auto flags =
|
||||
(0 == fs) ? nullptr : pod<SkCanvas::Lattice::RectType>(
|
||||
this, (xs + ys) * sizeof(int) + fs * sizeof(SkColor));
|
||||
SkPaint newPaint = paint;
|
||||
tonemapPaint(image->imageInfo(), c->imageInfo(), -1, newPaint);
|
||||
c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst, filter,
|
||||
&newPaint);
|
||||
c->drawImageLattice(image.get(), {xdivs, ydivs, flags, xs, ys, &src, colors}, dst,
|
||||
filter, &paint);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -18,10 +18,7 @@
|
||||
|
||||
#include <SkRuntimeEffect.h>
|
||||
#include <log/log.h>
|
||||
// libshaders only exists on Android devices
|
||||
#ifdef __ANDROID__
|
||||
#include <shaders/shaders.h>
|
||||
#endif
|
||||
|
||||
#include "utils/Color.h"
|
||||
|
||||
@@ -29,8 +26,6 @@ namespace android::uirenderer {
|
||||
|
||||
namespace {
|
||||
|
||||
// custom tonemapping only exists on Android devices
|
||||
#ifdef __ANDROID__
|
||||
class ColorFilterRuntimeEffectBuilder : public SkRuntimeEffectBuilder {
|
||||
public:
|
||||
explicit ColorFilterRuntimeEffectBuilder(sk_sp<SkRuntimeEffect> effect)
|
||||
@@ -64,21 +59,20 @@ static sk_sp<SkColorFilter> createLinearEffectColorFilter(const shaders::LinearE
|
||||
return effectBuilder.makeColorFilter();
|
||||
}
|
||||
|
||||
static ui::Dataspace extractTransfer(ui::Dataspace dataspace) {
|
||||
return static_cast<ui::Dataspace>(dataspace & HAL_DATASPACE_TRANSFER_MASK);
|
||||
static bool extractTransfer(ui::Dataspace dataspace) {
|
||||
return dataspace & HAL_DATASPACE_TRANSFER_MASK;
|
||||
}
|
||||
|
||||
static bool isHdrDataspace(ui::Dataspace dataspace) {
|
||||
const auto transfer = extractTransfer(dataspace);
|
||||
|
||||
return transfer == ui::Dataspace::TRANSFER_ST2084 || transfer == ui::Dataspace::TRANSFER_HLG;
|
||||
return transfer == HAL_DATASPACE_TRANSFER_ST2084 || transfer == HAL_DATASPACE_TRANSFER_HLG;
|
||||
}
|
||||
|
||||
static ui::Dataspace getDataspace(const SkImageInfo& image) {
|
||||
return static_cast<ui::Dataspace>(
|
||||
ColorSpaceToADataSpace(image.colorSpace(), image.colorType()));
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -86,8 +80,6 @@ static ui::Dataspace getDataspace(const SkImageInfo& image) {
|
||||
// shader and tag it on the supplied paint.
|
||||
void tonemapPaint(const SkImageInfo& source, const SkImageInfo& destination, float maxLuminanceNits,
|
||||
SkPaint& paint) {
|
||||
// custom tonemapping only exists on Android devices
|
||||
#ifdef __ANDROID__
|
||||
const auto sourceDataspace = getDataspace(source);
|
||||
const auto destinationDataspace = getDataspace(destination);
|
||||
|
||||
@@ -110,9 +102,6 @@ void tonemapPaint(const SkImageInfo& source, const SkImageInfo& destination, flo
|
||||
paint.setColorFilter(colorFilter);
|
||||
}
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace android::uirenderer
|
||||
|
||||
@@ -120,15 +120,6 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="ColorBitmapActivity"
|
||||
android:label="Bitmaps/BitmapColors"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="com.android.test.hwui.TEST"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="PathOffsetActivity"
|
||||
android:label="Path/Offset"
|
||||
android:exported="true">
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.test.hwui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorSpace;
|
||||
import android.graphics.HardwareBufferRenderer;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RenderNode;
|
||||
import android.graphics.Shader;
|
||||
import android.hardware.HardwareBuffer;
|
||||
import android.media.Image;
|
||||
import android.media.ImageWriter;
|
||||
import android.os.Bundle;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public class ColorBitmapActivity extends Activity implements SurfaceHolder.Callback,
|
||||
AdapterView.OnItemSelectedListener {
|
||||
|
||||
private static final int WIDTH = 512;
|
||||
private static final int HEIGHT = 512;
|
||||
|
||||
private ImageView mImageView;
|
||||
private SurfaceView mSurfaceView;
|
||||
private HardwareBuffer mGradientBuffer;
|
||||
private ImageWriter mImageWriter;
|
||||
private ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
|
||||
private String[] mColorNames = {"sRGB", "BT2020_HLG", "BT2020_PQ"};
|
||||
private String mCurrentColorName = "sRGB";
|
||||
|
||||
private FutureTask<HardwareBuffer> authorGradientBuffer(HardwareBuffer buffer) {
|
||||
HardwareBufferRenderer renderer = new HardwareBufferRenderer(buffer);
|
||||
RenderNode node = new RenderNode("content");
|
||||
node.setPosition(0, 0, buffer.getWidth(), buffer.getHeight());
|
||||
|
||||
Canvas canvas = node.beginRecording();
|
||||
LinearGradient gradient = new LinearGradient(
|
||||
0, 0, buffer.getWidth(), buffer.getHeight(), 0xFF000000,
|
||||
0xFFFFFFFF, Shader.TileMode.CLAMP);
|
||||
Paint paint = new Paint();
|
||||
paint.setShader(gradient);
|
||||
canvas.drawRect(0f, 0f, buffer.getWidth(), buffer.getHeight(), paint);
|
||||
node.endRecording();
|
||||
|
||||
renderer.setContentRoot(node);
|
||||
|
||||
ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
|
||||
FutureTask<HardwareBuffer> resolvedBuffer = new FutureTask<>(() -> buffer);
|
||||
renderer.obtainRenderRequest()
|
||||
.setColorSpace(colorSpace)
|
||||
.draw(Executors.newSingleThreadExecutor(), result -> {
|
||||
result.getFence().await(Duration.ofSeconds(3));
|
||||
resolvedBuffer.run();
|
||||
});
|
||||
return resolvedBuffer;
|
||||
}
|
||||
|
||||
private FutureTask<HardwareBuffer> getGradientBuffer() {
|
||||
HardwareBuffer buffer = HardwareBuffer.create(
|
||||
WIDTH, HEIGHT, PixelFormat.RGBA_8888, 1,
|
||||
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
|
||||
| HardwareBuffer.USAGE_GPU_COLOR_OUTPUT);
|
||||
return authorGradientBuffer(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
try {
|
||||
|
||||
mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
|
||||
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(
|
||||
this, android.R.layout.simple_spinner_item, mColorNames);
|
||||
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
Spinner spinner = new Spinner(this);
|
||||
spinner.setAdapter(adapter);
|
||||
spinner.setOnItemSelectedListener(this);
|
||||
|
||||
mGradientBuffer = getGradientBuffer().get();
|
||||
|
||||
LinearLayout linearLayout = new LinearLayout(this);
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
mImageView = new ImageView(this);
|
||||
|
||||
mSurfaceView = new SurfaceView(this);
|
||||
mSurfaceView.getHolder().addCallback(this);
|
||||
|
||||
linearLayout.addView(spinner, new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
linearLayout.addView(mImageView, new LinearLayout.LayoutParams(WIDTH, HEIGHT));
|
||||
linearLayout.addView(mSurfaceView, new LinearLayout.LayoutParams(WIDTH, HEIGHT));
|
||||
|
||||
setContentView(linearLayout);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private ColorSpace getFromName(String name) {
|
||||
if (name.equals("sRGB")) {
|
||||
return ColorSpace.get(ColorSpace.Named.SRGB);
|
||||
} else if (name.equals("BT2020_HLG")) {
|
||||
return ColorSpace.get(ColorSpace.Named.BT2020_HLG);
|
||||
} else if (name.equals("BT2020_PQ")) {
|
||||
return ColorSpace.get(ColorSpace.Named.BT2020_PQ);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unrecognized Colorspace!");
|
||||
}
|
||||
|
||||
private void populateBuffers() {
|
||||
Bitmap bitmap = Bitmap.wrapHardwareBuffer(
|
||||
mGradientBuffer, ColorSpace.get(ColorSpace.Named.SRGB));
|
||||
Bitmap copy = bitmap.copy(Bitmap.Config.ARGB_8888, false);
|
||||
copy.setColorSpace(mColorSpace);
|
||||
mImageView.setImageBitmap(copy);
|
||||
|
||||
try (Image image = mImageWriter.dequeueInputImage()) {
|
||||
authorGradientBuffer(image.getHardwareBuffer()).get();
|
||||
image.setDataSpace(mColorSpace.getDataSpace());
|
||||
mImageWriter.queueInputImage(image);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
mImageWriter = new ImageWriter.Builder(holder.getSurface())
|
||||
.setUsage(HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
|
||||
| HardwareBuffer.USAGE_GPU_COLOR_OUTPUT
|
||||
| HardwareBuffer.USAGE_COMPOSER_OVERLAY)
|
||||
.build();
|
||||
populateBuffers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
mImageWriter.close();
|
||||
mImageWriter = null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
mCurrentColorName = mColorNames[position];
|
||||
mColorSpace = getFromName(mCurrentColorName);
|
||||
populateBuffers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user