1
0
Fork 0

fix(gui): reduce rendering when adjusting image controls

This commit is contained in:
Sean Sube 2023-01-16 16:28:16 -06:00
parent 5d2c22a64a
commit 4615614e5e
4 changed files with 46 additions and 41 deletions

View File

@ -3,10 +3,11 @@ import { Casino } from '@mui/icons-material';
import { Button, Stack, TextField } from '@mui/material'; import { Button, Stack, TextField } from '@mui/material';
import * as React from 'react'; import * as React from 'react';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { useStore } from 'zustand';
import { BaseImgParams } from '../client.js'; import { BaseImgParams } from '../client.js';
import { ConfigParams, STALE_TIME } from '../config.js'; import { ConfigParams, STALE_TIME } from '../config.js';
import { ClientContext } from '../state.js'; import { ClientContext, OnnxState, StateContext } from '../state.js';
import { SCHEDULER_LABELS } from '../strings.js'; import { SCHEDULER_LABELS } from '../strings.js';
import { NumericField } from './NumericField.js'; import { NumericField } from './NumericField.js';
import { QueryList } from './QueryList.js'; import { QueryList } from './QueryList.js';
@ -15,7 +16,8 @@ const { useContext } = React;
export interface ImageControlProps { export interface ImageControlProps {
config: ConfigParams; config: ConfigParams;
params: BaseImgParams;
selector: (state: OnnxState) => BaseImgParams;
onChange?: (params: BaseImgParams) => void; onChange?: (params: BaseImgParams) => void;
} }
@ -24,7 +26,10 @@ export interface ImageControlProps {
* doesn't need to use state, the parent component knows which params to pass * doesn't need to use state, the parent component knows which params to pass
*/ */
export function ImageControl(props: ImageControlProps) { export function ImageControl(props: ImageControlProps) {
const { config, params } = props; const { config } = props;
const state = mustExist(useContext(StateContext));
const params = useStore(state, props.selector);
const client = mustExist(useContext(ClientContext)); const client = mustExist(useContext(ClientContext));
const schedulers = useQuery('schedulers', async () => client.schedulers(), { const schedulers = useQuery('schedulers', async () => client.schedulers(), {

View File

@ -24,13 +24,13 @@ export function Img2Img(props: Img2ImgProps) {
const { config, model, platform } = props; const { config, model, platform } = props;
async function uploadSource() { async function uploadSource() {
const upscale = state.getState().upscale; const { img2img, upscale } = state.getState();
const output = await client.img2img({ const output = await client.img2img({
...params, ...img2img,
model, model,
platform, platform,
source: mustExist(params.source), // TODO: show an error if this doesn't exist source: mustExist(img2img.source), // TODO: show an error if this doesn't exist
}, upscale); }, upscale);
setLoading(output); setLoading(output);
@ -43,7 +43,8 @@ export function Img2Img(props: Img2ImgProps) {
}); });
const state = mustExist(useContext(StateContext)); const state = mustExist(useContext(StateContext));
const params = useStore(state, (s) => s.img2img); const source = useStore(state, (s) => s.img2img.source);
const strength = useStore(state, (s) => s.img2img.strength);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
const setImg2Img = useStore(state, (s) => s.setImg2Img); const setImg2Img = useStore(state, (s) => s.setImg2Img);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
@ -51,21 +52,19 @@ export function Img2Img(props: Img2ImgProps) {
return <Box> return <Box>
<Stack spacing={2}> <Stack spacing={2}>
<ImageInput filter={IMAGE_FILTER} image={params.source} label='Source' onChange={(file) => { <ImageInput filter={IMAGE_FILTER} image={source} label='Source' onChange={(file) => {
setImg2Img({ setImg2Img({
source: file, source: file,
}); });
}} /> }} />
<ImageControl config={config} params={params} onChange={(newParams) => { <ImageControl config={config} selector={(s) => s.img2img} onChange={setImg2Img} />
setImg2Img(newParams);
}} />
<NumericField <NumericField
decimal decimal
label='Strength' label='Strength'
min={config.strength.min} min={config.strength.min}
max={config.strength.max} max={config.strength.max}
step={config.strength.step} step={config.strength.step}
value={params.strength} value={strength}
onChange={(value) => { onChange={(value) => {
setImg2Img({ setImg2Img({
strength: value, strength: value,

View File

@ -35,27 +35,26 @@ export function Inpaint(props: InpaintProps) {
async function uploadSource(): Promise<void> { async function uploadSource(): Promise<void> {
// these are not watched by the component, only sent by the mutation // these are not watched by the component, only sent by the mutation
const outpaint = state.getState().outpaint; const { inpaint, outpaint, upscale } = state.getState();
const upscale = state.getState().upscale;
if (outpaint.enabled) { if (outpaint.enabled) {
const output = await client.outpaint({ const output = await client.outpaint({
...params, ...inpaint,
...outpaint, ...outpaint,
model, model,
platform, platform,
mask: mustExist(params.mask), mask: mustExist(mask),
source: mustExist(params.source), source: mustExist(source),
}, upscale); }, upscale);
setLoading(output); setLoading(output);
} else { } else {
const output = await client.inpaint({ const output = await client.inpaint({
...params, ...inpaint,
model, model,
platform, platform,
mask: mustExist(params.mask), mask: mustExist(mask),
source: mustExist(params.source), source: mustExist(source),
}, upscale); }, upscale);
setLoading(output); setLoading(output);
@ -63,7 +62,10 @@ export function Inpaint(props: InpaintProps) {
} }
const state = mustExist(useContext(StateContext)); const state = mustExist(useContext(StateContext));
const params = useStore(state, (s) => s.inpaint); const filter = useStore(state, (s) => s.inpaint.filter);
const noise = useStore(state, (s) => s.inpaint.noise);
const mask = useStore(state, (s) => s.inpaint.mask);
const source = useStore(state, (s) => s.inpaint.source);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
const setInpaint = useStore(state, (s) => s.setInpaint); const setInpaint = useStore(state, (s) => s.setInpaint);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
@ -78,7 +80,7 @@ export function Inpaint(props: InpaintProps) {
<Stack spacing={2}> <Stack spacing={2}>
<ImageInput <ImageInput
filter={IMAGE_FILTER} filter={IMAGE_FILTER}
image={params.source} image={source}
label='Source' label='Source'
onChange={(file) => { onChange={(file) => {
setInpaint({ setInpaint({
@ -88,7 +90,7 @@ export function Inpaint(props: InpaintProps) {
/> />
<ImageInput <ImageInput
filter={IMAGE_FILTER} filter={IMAGE_FILTER}
image={params.mask} image={mask}
label='Mask' label='Mask'
onChange={(file) => { onChange={(file) => {
setInpaint({ setInpaint({
@ -98,11 +100,11 @@ export function Inpaint(props: InpaintProps) {
renderImage={(image) => renderImage={(image) =>
<MaskCanvas <MaskCanvas
config={config} config={config}
base={params.source} base={source}
source={image} source={image}
onSave={(mask) => { onSave={(file) => {
setInpaint({ setInpaint({
mask, mask: file,
}); });
}} }}
/> />
@ -110,7 +112,7 @@ export function Inpaint(props: InpaintProps) {
/> />
<ImageControl <ImageControl
config={config} config={config}
params={params} selector={(s) => s.inpaint}
onChange={(newParams) => { onChange={(newParams) => {
setInpaint(newParams); setInpaint(newParams);
}} }}
@ -121,10 +123,10 @@ export function Inpaint(props: InpaintProps) {
labels={MASK_LABELS} labels={MASK_LABELS}
name='Mask Filter' name='Mask Filter'
result={masks} result={masks}
value={params.filter} value={filter}
onChange={(filter) => { onChange={(newFilter) => {
setInpaint({ setInpaint({
filter, filter: newFilter,
}); });
}} }}
/> />
@ -133,10 +135,10 @@ export function Inpaint(props: InpaintProps) {
labels={NOISE_LABELS} labels={NOISE_LABELS}
name='Noise Source' name='Noise Source'
result={noises} result={noises}
value={params.noise} value={noise}
onChange={(noise) => { onChange={(newNoise) => {
setInpaint({ setInpaint({
noise, noise: newNoise,
}); });
}} }}
/> />

View File

@ -23,9 +23,9 @@ export function Txt2Img(props: Txt2ImgProps) {
const { config, model, platform } = props; const { config, model, platform } = props;
async function generateImage() { async function generateImage() {
const upscale = state.getState().upscale; const { txt2img, upscale } = state.getState();
const output = await client.txt2img({ const output = await client.txt2img({
...params, ...txt2img,
model, model,
platform, platform,
}, upscale); }, upscale);
@ -40,7 +40,8 @@ export function Txt2Img(props: Txt2ImgProps) {
}); });
const state = mustExist(useContext(StateContext)); const state = mustExist(useContext(StateContext));
const params = useStore(state, (s) => s.txt2img); const height = useStore(state, (s) => s.txt2img.height);
const width = useStore(state, (s) => s.txt2img.width);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
const setTxt2Img = useStore(state, (s) => s.setTxt2Img); const setTxt2Img = useStore(state, (s) => s.setTxt2Img);
// eslint-disable-next-line @typescript-eslint/unbound-method // eslint-disable-next-line @typescript-eslint/unbound-method
@ -48,16 +49,14 @@ export function Txt2Img(props: Txt2ImgProps) {
return <Box> return <Box>
<Stack spacing={2}> <Stack spacing={2}>
<ImageControl config={config} params={params} onChange={(newParams) => { <ImageControl config={config} selector={(s) => s.txt2img} onChange={setTxt2Img} />
setTxt2Img(newParams);
}} />
<Stack direction='row' spacing={4}> <Stack direction='row' spacing={4}>
<NumericField <NumericField
label='Width' label='Width'
min={config.width.min} min={config.width.min}
max={config.width.max} max={config.width.max}
step={config.width.step} step={config.width.step}
value={params.width} value={width}
onChange={(value) => { onChange={(value) => {
setTxt2Img({ setTxt2Img({
width: value, width: value,
@ -69,7 +68,7 @@ export function Txt2Img(props: Txt2ImgProps) {
min={config.height.min} min={config.height.min}
max={config.height.max} max={config.height.max}
step={config.height.step} step={config.height.step}
value={params.height} value={height}
onChange={(value) => { onChange={(value) => {
setTxt2Img({ setTxt2Img({
height: value, height: value,